В процессе реализации init(coder:)
для пользовательского подкласса NSView я натолкнулся на странное поведение с NSKeyedArchiver и NSKeyedUnarchiver, которое я до сих пор не совсем понимаю. Рассмотрим этот пример кода:
let label = NSTextField(labelWithString: "Test")
// Encode
let data = try NSKeyedArchiver.archivedData(withRootObject: label, requiringSecureCoding: false)
// Decode
try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? NSTextField
Похоже, это кодирует и декодирует NSTextField, как и ожидалось. Однако, если я попытаюсь использовать decodeTopLevelObject()
вместо unarchiveTopLevelObjectWithData(_:)
, результат будет nil
:
// Encode
let data = try NSKeyedArchiver.archivedData(withRootObject: label, requiringSecureCoding: false)
// Decode
let decoder = try NSKeyedUnarchiver(forReadingFrom: data)
decoder.decodeTopLevelObject() as? NSTextField // nil
Аналогично, если я попытаюсь использовать encodedData
вместо archivedData(withRootObject:requiringSecureCoding:)
, результат будет nil
:
// Encode
let coder = NSKeyedArchiver(requiringSecureCoding: false)
coder.encodeRootObject(label)
let data = coder.encodedData
// Decode
try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? NSTextField // nil
Результат даже nil
, если я использую encode(_:forKey:)
и decodeObject(forKey:)
:
// Encode
let coder = NSKeyedArchiver(requiringSecureCoding: false)
coder.encode(label, forKey: "label")
let data = coder.encodedData
// Decode
let decoder = try NSKeyedUnarchiver(forReadingFrom: data)
decoder.decodeObject(forKey: "label") as? NSTextField // nil
Я удивлен, что первый приведенный выше пример работает правильно, но ни один из них не работает (особенно последний). Может ли кто-нибудь помочь мне понять, что здесь происходит?