OC中使用KVC是因为NSObject遵循了NSKeyValueCoding协议,而OC中所有的类包括自定义类的根类都是NSObject,所以都能使用KVC特性,但是Swift中的类其实是没有统一的根类的(自定义一个类理论上也不需要继承任何父类),所以KVC可以说是OC中的特性,
要想在Swift中也使用KVC,我们就得将自定义的类继承NSObject(理论上遵循NSKeyValueCoding协议也是可以的,但没必要呀~)。但光是继承是不够的,比如下面这段代码:
Example类已经继承自NSObject,这时候可以使用KVC功能获取title的值,但是第16行代码在调用的时候会抛出下面的运行时异常:
this class is not key value coding-compliant for the key xxxx,字面意思是没有找到与键为“xxxx”兼容的键值对,这就奇了怪了,明明定义了这个实例变量,这里却说找不到。
其实原因上面已经说到过了:KVC是OC的特性!
那么我们在Swift类中定义的实例变量OC肯定是没法访问的了,所以在调用value(forKey:)、setValue(forKey:)等KVC方法的时候就会报找不到的错。
解决方法:在实例变量的前面加上@objc进行修饰,如下:
这样就不会抛异常了。
解释下@objc的作用:
1.允许函数或属性通过OC的消息机制进行调用(即调用objc_msgSend,KVC其实也是基于runtime,swift貌似没有OC的runtime机制的,Swift是静态语言,不过可以间接使用runtime机制,后面再去花时间研究,所以上面问题的核心原理就在这里)
2.对Swift的函数或属性做一个面向OC的翻译,比如@objc func test()->Void{}这个方法就会被翻译成-(void)test{}
3.其他的就等你去发觉然后告诉我啦~~~