- [CALayer retain]: сообщение отправлено освобожденному экземпляру - PullRequest
4 голосов
/ 13 июля 2010

Я разрабатываю приложение для iphone, и когда я включаю свой NSZombieEnabled, у меня регулярно происходит сбой при ошибке:

*** -[CALayer retain]: message sent to deallocated instance 0xe6012e0

Это всегда происходит, когда я нажимаю или выталкиваю представление в моем контроллере представления.Иногда возникает такая ошибка:

-[UIApplication endIgnoringInteractionEvents] called without matching -beginIgnoringInteractionEvents. Ignoring.

Что это значит?У кого-нибудь есть подсказка или возникла эта проблема?

Большое спасибо за помощь!

Romain

Ответы [ 3 ]

14 голосов
/ 27 июля 2011

Это, вероятно, означает, что вы пытаетесь сохранить объект, объект UI, например UIButton, который был освобожден. Есть несколько способов отследить эту проблему, но если вы можете сузить, где это происходит в вашем приложении, я обычно начинаю комментировать выпуски, пока не увижу, где находится проблемный выпуск. Полагаю, вы выпустили нечто, что было выпущено автоматически.

1 голос
/ 28 апреля 2017

Если приведенные выше ответы не помогли, проверьте, использует ли ваш код KVO в классе, в котором вы получили эту ошибку.Когда KVO отправляет сообщение вашему классу наблюдения о значении изменения ключа, если класс был освобожден ARC, тогда KVO будет пытаться предупредить несуществующий адрес в памяти об этих изменениях, заставляя ваше приложение выбросить этоошибка.

Учтите, что это класс с именем MyViewController, и вы хотите наблюдать, когда свойство bounds его view.layer меняется, указывая на изменение макета с альбомного на портретный.Таким образом, вы добавляете строку:

// self is MyViewController
self.view.layer.addObserver(self, forKeyPath: "bounds", options: .new, context: nil)

Это предупредит ваш класс, если размер view изменился.

Но если ваш viewController отклоняется, скажем, UINavigationController выталкивает его из стека, KVO все еще собирается попытаться предупредить MyViewController границы представления изменились (потому что теперь он исчез).Затем, когда KVO сделает это, ваше приложение будет аварийно завершено.В консоли отладки вы увидите следующее сообщение:

-[MyViewController retain]: message sent to deallocated instance

Это потому, что вы должны удалить наблюдателя (MyViewController) для этого keyPath.Лучше сделать это до того, как MyViewController будет отклонен, то есть так:

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.view.layer.removeObserver(self, forKeyPath: "bounds")
}

Теперь, когда вы попытаетесь извлечь MyViewController из стека навигации, ошибки не будет.

1 голос
/ 12 мая 2014

Я хотел бы получить что-то большее, чем @Tony ответ.Как это правильно.

Возможно, вы используете UI object's layer или sublayer.Так что просто проверьте, что пользовательский интерфейс не был выпущен перед его использованием;

if(UI object) //has instance
{
   //now use UI object.
}
...