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