在Int上使用setValue(value,forKey:key)?类型触发非键值编码兼容方法

时间:2014-09-30 10:44:36

标签: swift nsnumber key-value-coding nskeyvaluecoding

我在符合NSKeyValueCoding的Swift NSObject子类中成功使用setValue(value, forKey: key)方法。

这非常适用于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中使用过 - 在Int类型上成功的NSKeyValueCoding方法setValue(value, forKey: key)

2 个答案:

答案 0 :(得分:24)

KVO无法使用纯Swift选项,因为纯Swift选项不是Objective-C对象。 Swift禁止将dynamic@objc与泛型类和结构一起使用,因为没有有效的Objective-C等价物,因此运行时未设置为在这些类型的对象的实例上支持KVO。至于为什么它与String?一起使用,该类型是免费桥接到NSString,因此它在语义上等同于NSString *,一种运行时知道全井的Objective-C类型怎么处理。但请将其与Int?进行比较,其语义等效项为Optional<Int>,而不是UnsafePointer<Int>NSNumber *。目前,您需要说服类型检查员使用NSNumber!在Objective-C中表示是安全的。

这完全是倒退的,在我看来,这是类型系统的一个不幸的限制。对于遇到过这篇文章的工程师,请参阅rdar:// 18624182。

答案 1 :(得分:3)

如果你愿意放弃Swift类型改变:

var myId:Int?

为:

var myId:NSNumber?