Используя setValue(значение, forKey: ключ) на Int? типы запускают метод, не совместимый со значением ключа
Я успешно использую setValue(value, forKey: key)
метод в моем подклассе Swift NSObject, совместимом с NSKeyValueCoding.
Это отлично работает на опциях String, например
var name:String?
Тем не менее, для опций Int это не удается, вызывая метод неопределенного ключа, который я переопределил для целей отладки:
override func setValue(value: AnyObject!, forUndefinedKey key: String!) {
println("\(self) this class is not key value coding-compliant for the key \(key)")
}
Так, например, ключ myId
с хорошим целочисленным значением вызовет метод неопределенного ключа выше.
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 успешно?
2 ответа
KVO не может работать с чистыми опционами Swift, потому что чистые опционы Swift не являются объектами Objective-C. Swift запрещает использование dynamic
или же @objc
с универсальными классами и структурами, потому что нет действительного эквивалента Objective-C, и поэтому среда выполнения не настроена для поддержки KVO на экземплярах объектов такого типа. Что касается того, почему это работает с String?
этот тип бесплатный для моста NSString
так что это семантически эквивалентно NSString *
тип Objective C, с которым среда выполнения хорошо знает, что делать. Но сравните это с Int?
чей семантический эквивалент будет Optional<Int>
не UnsafePointer<Int>
или же NSNumber *
как и следовало ожидать. На данный момент вам нужно убедить проверщика типов в том, что его безопасно представлять в Objective-C, используя NSNumber!
,
Это полностью задом наперед и, на мой взгляд, неудачное ограничение системы типов. Для всех инженеров, которые сталкиваются с этим постом, см. Rdar://18624182.
Если вы готовы отказаться от Swift, поменяйте тип:
var myId:Int?
чтобы:
var myId:NSNumber?