Я недавно начал разрабатывать свое приложение с iOS 11 в качестве целевой версии, потому что это было значение по умолчанию. Сейчас я снизил версию до 9.3 по причинам.
Приложение - чистый swift 4, с использованием нового блока блоков KVO.
Я исправил несколько ошибок времени компиляции, которые у меня были с safeAreaInsets
и еще много чего, и приложение успешно собралось. Быстрая работа. Ницца.
Я попытался запустить его на iPhone 7 iOS 10.3.1 Simulator, и, господин, это был крушение поезда. Я думаю, 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
, который наблюдает 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-блока решит мир во всем мире, но, очевидно, это применимо только к 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")
}
Но я получаю вывод, говорящий Can't remove because it is not registered as an observer
. Так что я думаю MyViewController
не на самом деле наблюдатель, который привязывается при использовании этого нового KVO.
Почему ничего из этого не работало? Где и когда мне нужно удалить наблюдателей в