2014-09-30 11 views
25

我在符合NSKeyValueCoding的Swift NSObject子类中成功使用了setValue(value, forKey: key)方法。在Int上使用setValue(value,forKey:key)类型触发非关键值编码兼容方法

这对字符串选项非常适用,例如,

var name:String? 

然而,在诠释自选,失败,引发我已经覆盖了调试的目的未定义的关键方法:

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) 

所以,问题是,已经没有人使用 - 斯威夫特 - 该方法的NSKeyValueCoding setValue(value, forKey: key)上int类型成功?

+1

难道这是因为int是任何类型,而不是AnyObject的。我试图解析一个对象到字典并返回,并有类似的问题。请参阅https://github.com/evermeer/EVCloudKitDao/blob/master/AppMessage/AppMessage/CloudKit/EVReflection.swift您可以看到我尝试将Any解析为AnyObject。可空值仍然是一个问题,但它在Int上起作用。 – 2014-09-30 22:13:32

回答

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

我认为这篇文章有一些技术上的不准确之处。 1)我已将'Int?'更改为'NSNumber?',现在它完全符合KVO。2)KVO可以使用optionals,因为我可以使用'UIColor?','NSNumber?'和其他objc类型。 3)可选项是特殊处理的泛型,甚至使用'不可空','可空',等等添加到Objc中。等等。 – Mazyod 2015-02-28 12:43:29

+0

1由第一段的最后一句,第二句的第3句和第3句错误暗示。可选项由运行时桥接到一组有限的ObjC类型,但它们不能完全用新的可空属性来表示。此外,这是关于Swift结构和KVO,而不是Objective-C结构的桥接。 – CodaFi 2015-02-28 14:23:58

3

如果你愿意沟斯威夫特类型的改变:

var myId:Int? 

到:

var myId:NSNumber? 
相关问题