Я преобразовал свое приложение в ARC и заметил, что объект, выделенный в одном из моих контроллеров, не был освобожден, когда этот контроллер просмотра был удален. Понадобилось время, чтобы понять, почему. У меня есть Enable Zombie Objects для моего проекта во время отладки, и это оказалось причиной. Рассмотрим следующую логику приложения:
1) Пользователи запускают действие в RootViewController
, которое вызывает создание SecondaryViewController
и представлен через presentModalViewController:animated
.
2) SecondaryViewController
содержит ActionsController
, который является подклассом NSObject
.
3) ActionsController
наблюдает уведомление через NSNotificationCenter
, когда оно инициализируется и перестает наблюдать, когда оно отменено.
4) Пользователь отклоняет SecondaryViewController
, чтобы вернуться к RootViewController
.
С отключением объектов Zombie отключены, это работает отлично, все объекты освобождены. При включении объектов Zombie на ActionsController
не освобождается, даже если SecondaryViewController
освобождается.
Это вызвало проблемы в моем приложении b/c NSNotificationCenter
продолжает отправлять уведомления на ActionsController
, а получающиеся обработчики приводят к сбою приложения.
Я создал простое приложение, иллюстрирующее это на https://github.com/xjones/XJARCTestApp. Посмотрите на журнал консоли с включением/выключением объектов Zombie. Чтобы проверить это, выполните следующие действия.
Вопрос (ы)
- Это правильное поведение Enable Zombie Objects?
- Как я должен реализовать этот тип логики, чтобы устранить проблему. Я хотел бы продолжать использовать Enable Zombie Objects.
EDIT # 1: по предложению Кевина Я отправил это в Apple и openradar на http://openradar.appspot.com/10537635.
РЕДАКТИРОВАТЬ # 2: пояснение на хороший ответ
Во-первых, я опытный разработчик iOS, и я полностью понимаю ARC, объекты зомби и т.д. Если мне что-то не хватает, я, конечно, ценю любое освещение.
Во-вторых, верно, что обходной путь для этого конкретного сбоя заключается в удалении ActionsController
в качестве наблюдателя, когда SecondaryViewController
освобождается. Я также обнаружил, что если я явно устанавливаю actionsController = nil
, когда SecondaryViewController
отменяется, он будет отменен. Оба эти метода не являются обходным решением b/c, поэтому они требуют, чтобы вы использовали ARC, но код, как если бы вы не использовали ARC (например, nil iVars явно в dealloc). Конкретное решение также не помогает определить, когда это будет проблемой в других контроллерах, поэтому разработчики детерминистски знают, когда/как это решить.
Хороший ответ объяснит, как детерминистически знать, что вам нужно делать что-то особенное по отношению к объекту при использовании ARC + NSZombieEnabled, чтобы он разрешил этот конкретный пример и также применил в целом к проекту в целом без оставления потенциала для других подобных проблем.
Вполне возможно, что хорошего ответа не существует, поскольку это может быть ошибкой в XCode.
спасибо всем!