정의
A protocol that enables an object to be encoded and decoded for archiving and distribution.
아카이빙과 배포를 위해 객체가 encoding과 decoding을 가능케 도와주는 프로토콜이다.
조금 더 자세히 설명하면 NSCoding은 Objective-C 기반의 클래스를 직렬화 및 역직렬화를 하는 역할을한다.
인코딩이란?
Swift의 데이터를 컴퓨터가 이해할 수 있는 0과1로 코드화, 암호화 등을 하는 과정이고
보안, 저장 공간 절약등의 효과를 볼 수 있다.
디코딩이란?
디코딩은 인코딩의 정확한 반대 과정으로 복호화, 역코드화가 진행되며
컴퓨터가 이해할 수 있는 정보를 우리가 사용하는 Swift 데이터로 바꾸는 과정이다.
구성
public protocol NSCoding {
func encode(with coder: NSCoder)
init?(coder: NSCoder) // NS_DESIGNATED_INITIALIZER
}
1. init?(coder: NSCoder)
프로토콜의 구성이 많이 익숙해 보인다..
생성자 쪽이 UIKit에서 UIView를 상속 받았을 때 requird가 붙어있는 생성자와 똑같이 생겼다.
역할은 coder에 들어있는 data(바이너리 데이터)를 이용하여 해당 오브젝트를 초기화 할 수 있는 정보를 준다.
즉, 디코딩을 진행하는 통해 프로퍼티를 초기화하는 공간이다.
2. func encode(with coder: NSCoder)
오브젝트가 자신에게 제공받은 coder를 통해 인스턴스 변수를 인코딩하도록 도와준다.
즉, 저장하고 싶은 값을 corder를 통해 인코딩하는 과정이다.
정리
어떤 오브젝트 클래스가 codeable ( encoding 과 decoding이 가능한) 하려면 반드시 NSCoding 프로토콜를 채택하여 그 요구사항을 구현해야 한다.
사용 예시
객체를 아카이빙(보관) 하고 싶다면 NSObjcet 를 상속하고, NSCoding 프로토콜을 구현하면 된다.
하지만 구조체는 아카이빙 할 수 없다. 구조체의 경우 Encodable 과 Decodable 프로토콜을 이용한다.
nscoding을 사용하던 중 다음과 같은 에러를 만났다.
Error Domain=NSCocoaErrorDomain Code=4864
"This decoder will only decode classes that adopt NSSecureCoding.
자세히 보니 Secure이란 단어가 붙어있는 NSCoidng과 유사한 느낌의 무언가가 있다.
그래서 NSCoding과 차이점을 알아보기 위해서 추가로 작성한다.
정의
A protocol that enables encoding and decoding in a manner that is robust against object substitution attacks.
Object Substitution 공격에 맞서기 위한 강력한 Encoding, Decoding 방식을 가능하게하는 프로토콜이다.
객체 치환 공격이란?
if let object = decoder.decodeObjectForKey("myKey") as MyClass {
// ...succeeds...
} else {
// ...fail...
}
많은 클래스들은 자신 클래스의 인스턴스를 디코딩하는 데 위와 같이 한다.
MyClass를 활용하여 MyClass라는 타입을 타입캐스팅을 통해 가져온다.
이런 디코딩의 경우, 클래스의 타입을 확인할 때, 이미 object가 생성된 상태이며, 만약 이것이 컬렉션 클래스의 일부라면,
잠재적으로 object graph에 삽입될 수도 있기에 안전하지 않은 방법이다.
결국 Object가 생성되기 전에 클래스의 타입을 확정짓기 못하기 때문에 안전하지 않다는 결론으로 생각된다.
구성
public protocol NSSecureCoding : NSCoding {
static var supportsSecureCoding: Bool { get }
}
NScoding을 채택하므로 위에서 설명한 init?(coder:)와 func encode(with:)는 당연히 채택을 해야하고
특이한 변수 supportsSecureCoding가 눈에 띈다.
간단히 말하면 secure coding을 지원하는 클래스인지 아닌지 여부를 판단하는 속성값이다.
Seucre Coding을 지원하는 Class를 작성할 때, 이 클래스 프로퍼티의 getter 반환 값이 true임을 보장해야한다.
만약 Secure를 사용하면 디코딩 과정이 어떻게 버뀔까??
적용 후 차이점
class MyClass: NSObject, NSSecureCoding {
// ...
}
class SomeOtherClass {
var myClass: MyClass?
init(coder: NSCoder) {
let object = coder.decodeObject(of: MyClass.self, forKey: "myClass")
}
}
참고
'iOS > UIKit' 카테고리의 다른 글
UISearchController (1) | 2024.10.06 |
---|---|
NSKeyedArchiver (0) | 2024.09.11 |
NSObject (1) | 2024.09.10 |
UIGraphics (0) | 2024.09.06 |
UIGestureRecognizer (0) | 2024.09.05 |