我最近开始开发我的应用程序,目标版本为iOS 11,因为这是默认值。现在我将版本降低到9.3,因为一些原因。
该应用程序是纯Swift 4编写的,使用了新的KVO块。我修复了几个编译时错误,如“safeAreaInsets”等,并且应用程序构建成功。快速完成。不错。
我尝试在iPhone 7 iOS 10.3.1模拟器上运行它,结果崩溃了。我猜以前可能没有使用“UITableViewAutomaticDimension”。
无论如何,我已经解决了大部分布局问题,但现在我卡在了一些难以解决的崩溃问题上。我在导航推送的ViewController中使用了这个新的KVO,当我导航返回时它会崩溃。我的导航推送ViewController在其持有的对象内监听KVO字段。当我弹出导航时,ViewController和对象都被释放,应用程序崩溃,并提示以下错误:
据我所知,它表示在某人观察变量isSelected时,观察对象MyObject已被释放。这是在MyViewController中观察MyObject的代码。
但这并没有帮助。我也尝试了以下操作:
该应用程序是纯Swift 4编写的,使用了新的KVO块。我修复了几个编译时错误,如“safeAreaInsets”等,并且应用程序构建成功。快速完成。不错。
我尝试在iPhone 7 iOS 10.3.1模拟器上运行它,结果崩溃了。我猜以前可能没有使用“UITableViewAutomaticDimension”。
无论如何,我已经解决了大部分布局问题,但现在我卡在了一些难以解决的崩溃问题上。我在导航推送的ViewController中使用了这个新的KVO,当我导航返回时它会崩溃。我的导航推送ViewController在其持有的对象内监听KVO字段。当我弹出导航时,ViewController和对象都被释放,应用程序崩溃,并提示以下错误:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7fdf2e724250 of class MyProject.MyObject was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x60800003fd80> (
<NSKeyValueObservance 0x610000050020: Observer: 0x61000006f140, Key path: isSelected, Options: <New: NO, Old: NO, Prior: NO> Context: 0x0, Property: 0x6180000595f0>
)'
据我所知,它表示在某人观察变量isSelected时,观察对象MyObject已被释放。这是在MyViewController中观察MyObject的代码。
var observations:[NSKeyValueObservation] = []
func someFunction() {
observations.removeAll()
let myObject = MyObject(/*init*/)
self.myObject = myObject
observations.append(myObject.observe(\.isSelected, changeHandler: { [weak self] (object, value) in
//Do stuff
}))
}
我本以为这种新的KVO-block-style能解决世界和平问题,但显然只适用于iOS 11。
现在,我已经尝试了一些方法,但是我无法阻止它崩溃。每次都会发生,我不知道为什么。
由于崩溃日志告诉我被观察对象在有对象观察它时被释放,但我也知道观察对象在被观察对象之前被释放,所以我尝试在观察者中做如下操作:
//In MyViewController
deinit {
observations.forEach({$0.invalidate()})
observations.removeAll()
print("Observers removed")
}
但这并没有帮助。我也尝试了以下操作:
//In MyObject
deinit{
print("MyObject deinit")
}
当我执行此操作时,会得到以下输出:
>Observers removed
>MyObject deinit
>WORLD WAR 5 STACK TRACE
我也尝试过
//In MyViewController
deinit{
self.myObject.removeObserver(self, forKeyPath: "isSelected")
}
但是我得到的输出结果是 无法删除,因为它未注册为观察者
。所以我猜测 MyViewController
并不是在使用这个新的 KVO 时被附加的观察者。
为什么这些都没有起作用呢?在 < iOS11 中,我何时需要移除观察者?
deinit
实际上被调用了吗? (2) 你完全正确,运行在 iOS 10 及之前版本上是个问题;在 iOS 11 中,如果观察者或被观察者先消失,就不会有问题。 - matt