如果文章对您有用,麻烦顺手点一下文章的广告吧~

东东

Swift结合RxSwift使用KVO崩溃问题
Terminating app due to uncaught exception 'NSUnknownKeyEx...
扫描右侧二维码阅读全文
12
2019/09

Swift结合RxSwift使用KVO崩溃问题

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<LazypigQuickly.LZCreateThingsVC 0x7fd6765097e0> addObserver:<_TtC7RxCocoaP33_F7515DBB13B60709A3CB25DD19EDD11D11KVOObserver 0x600001ae4540> forKeyPath:@"mTest.name" options:5 context:0x0] was sent to an object that is not KVC-compliant for the "mTest" property.'

在观察某个属性更改做出某种动作,使用KVO简单便捷。

混编的问题,OC 是基于运行时,遵循了 KVC 和动态派发,而 Swift 为了追求性能,在编译时就已经确定,而不需要在运行时的,在 Swift 类型文件中,为了解决这个问题,需要暴露给 OC 使用的任何地方(类,属性,方法等)的生命前面加上 @objc 修饰符

所以在swift使用KVO时,如果没有对象没有涉及@objc标签,就会出现上述报错sent to an object that is not KVC-compliant for the "mTest" property.

所以加上@objc即可。

如果只使用属性,可以只加属性上

class Test: NSObject {
    @objc dynamic var name = "sssss"
    
}

var mTest = Test()
let observable = self.mTest.rx.observe(String.self, "name")
observable.subscribe({ (name) in
      print(name)
})

如果使用self调用,那么对象前面也需要加上@objc

class Test: NSObject {
    @objc dynamic var name = "sssss"
    
}

@objc var mTest = Test()
let observable = self.rx.observe(String.self, "mTest.name")
observable.subscribe({ (name) in
      print(name)
})

网上提到如果用 Swift 写的 class 是继承 NSObject 的话, Swift 会默认自动为所有非 private 的类和成员加上@objc,但是在例子中Test如果不显式添加@objc标签,崩溃了,查了查资料

Swift 3 中继承自 NSObject 的类,不需要手动添加 @objc ,编译器会给所有的非 private 的类和成员加上 @objc , private 接口想要暴露给 Objective-C 需要 @objc 的修饰。Swift4 后继承自 NSObject 的类不再隐式添加 @objc 关键字

关于@objc、@objcMembers和dynamic的含义,可以参考:Swift3、4中的@objc、@objcMembers和dynamic

Last modification:September 24th, 2019 at 11:20 am
如果觉得我的文章对你有用,请随意打赏: ☞已打赏列表

Leave a Comment