Используя 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?
Другие вопросы по тегам