我最近开始使用iOS 11开发我的应用程序作为目标版本,因为这是默认值。由于原因,我现在将版本降低到9.3。
该应用程序是纯粹的快速4,使用新的KVO块事物。
我用safeAreaInsets
和诸如此类的东西修复了我遇到的一些编译时错误,并成功构建了应用程序。一份快速的工作。好的。
我尝试在iPhone 7 iOS 10.3.1模拟器上运行它,并且主 - 这是一个火车残骸。我想UITableViewAutomaticDimension
在这些日子里并不是真的回事。
无论如何,我已经解决了大部分布局问题,但现在我遇到了一些硬崩溃问题。无论何时我都使用过这款新的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>
)'
据我所知,它表示观察到的对象MyObject
被释放,而有人观察变量isSelected
。
这是观察MyViewController
的{{1}}中的oberservation代码。
MyObject
我的印象是,这种新的神奇KVO-block风格会解决世界和平问题,但显然只适用于iOS 11。
现在,我已经尝试了一些事情,但我无法让它崩溃。它每次都会发生,我不明白为什么。
由于崩溃日志告诉我观察对象在对象观察时被解除分配,但我也知道观察对象在观察对象之前被释放,我已经尝试在观察者中执行此操作:
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
}))
}
但这并没有帮助。我也这样做了:
//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")
}
。所以我猜Can't remove because it is not registered as an observer
为什么没有这项工作?我必须在何时何地删除&lt;中的观察者? iOS11?
答案 0 :(得分:7)
看起来你遇到了一年前我报道的一个错误,但不幸的是很少受到关注:
https://bugs.swift.org/browse/SR-5752
由于这个bug在一段时间内没有让我感到困惑,我原本希望它已经在Swift叠加层中修复了,但我只是尝试将我的代码从bug报告复制到iOS项目并在10.3中运行它.1模拟器,果然,崩溃又回来了。
你可以这样解决:
deinit {
for eachObservation in observations {
if #available(/*whichever version of iOS fixes this*/) { /* do nothing */ } else {
self.removeObserver(eachObservation, forKeyPath: #keyPath(/*the key path*/))
}
eachObservation.invalidate()
}
observations.removeAll()
}
请确保您只在受此bug影响的iOS版本上执行此操作,否则您将删除已被删除的观察,然后 可能会崩溃。这不好玩吗?