Использование setValue (значение, forKey: key) в Int? типы запускают метод нестандартного кодирования
Я успешно использую метод setValue(value, forKey: key)
в своем подклассе Swift NSObject под NSKeyValueCoding.
Это прекрасно работает с опциями String, например
var name:String?
Однако, на опциях Int, он не работает, вызывая метод ключа undefined, который я переопределил для целей отладки:
override func setValue(value: AnyObject!, forUndefinedKey key: String!) {
println("\(self) this class is not key value coding-compliant for the key \(key)")
}
Итак, например, ключ myId
с хорошим целочисленным значением вызовет метод ключа undefined выше.
var myId:Int?
Если я изменил вышеприведенное определение как необязательное, тогда все работает нормально:
var myId:Int = 0
С myId
как факультативным, я пробовал абсолютно все, что я могу себе представить, в способе кастинга, разворачивания, инициализации и т.д. Он просто не видит класс как ключевое значение, совместимое для этих числовых значений.
Я знаю, что это хорошее числовое значение. Изменение объявления var в String? сбои. Он также отлично выглядит в lldb:
Printing description of key:
myId
key NSObject 0x00007fb8d530ca20 0x00007fb8d530ca20
k NSString "myId" 0x00007fa2aa942f20
value __NSCFNumber * Int64(4348129) 0xb000000004258e13
Printing description of value:
4348129
(lldb)
Итак, вопрос в том, кто-нибудь использовал - в Swift - метод NSKeyValueCoding setValue(value, forKey: key)
для типа Int успешно?
Ответы
Ответ 1
KVO не может работать с чистыми опциями Swift, поскольку чистые опции Swift не являются объектами Objective-C. Swift запрещает использование dynamic
или @objc
с помощью общих классов и структур, потому что нет действительного эквивалента Objective-C, поэтому среда выполнения не настроена для поддержки KVO для экземпляров этих объектов. Что касается того, почему он работает с String?
, этот тип не связан с мостом на NSString
, поэтому он семантически эквивалентен типу NSString *
, Objective-C, который среда выполнения знает о том, как справиться. Но сравните это с Int?
, семантический эквивалент которого будет Optional<Int>
, а не UnsafePointer<Int>
или NSNumber *
, как вы могли бы ожидать. На данный момент вам нужно убедить typechecker, что в Objective-C можно безопасно представлять с помощью NSNumber!
.
Это полностью назад и, на мой взгляд, неудачное ограничение системы типов. Для любых инженеров, которые сталкиваются с этим сообщением, см. Rdar://18624182.
Ответ 2
Если вы хотите сбросить типы Swift:
var myId:Int?
в
var myId:NSNumber?