Какао: поиск недостающей ссылки для освобождения

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

Я делаю это несколько раз, и, насколько я понимаю, не должно быть значительного роста кучи, потому что я возвращаюсь в одно и то же место, все, что я делал между ними, должно было быть освобождено, не обеспечивая роста кучи. Однако у меня значительный рост, поэтому я погружаюсь в кучи и обнаруживаю, что почти все в нем имеет счетчик сохранения, равный 1, что заставляет меня поверить, что один объект или представление и т. д. не освобождаются из-за ошибки, которую я сделал и этот объект содержит ссылки на все остальное.

Я пытаюсь выяснить, какой объект не освобождается. Инструменты очень расплывчаты и предлагают только неясные указатели, которые не позволяют мне проследить проблему.

Пожалуйста, дайте мне знать, есть ли у меня способ отследить, что содержит ссылку, которая может поддерживать счетчик удержания на уровне 1.

Спасибо.


person Elbimio    schedule 29.07.2013    source источник


Ответы (1)


Моя первая мысль состоит в двух вещах:
1) У вас может быть цикл сохранения: например, один объект должен делегировать сильную ссылку. И делегат также имеет сильную ссылку (вместо слабой ссылки) на 1-й объект назад. Поскольку оба они «удерживают» друг друга, ни один из них не может быть освобожден.
2) Возможно, у вас многопоточное приложение, одному из потоков не назначен пул автоматического освобождения (т. е. нет @autoreleasepool block) и создает объекты автоосвобождения. Это может произойти даже в простом методе получения, который возвращает объект автовыпуска. Если это так, объект автоматического освобождения "помещается" в несуществующий пул автоматического освобождения (который не выдает вам сообщение об ошибке, поскольку вы можете отправить любое сообщение nil) и никогда не освобождается.
Возможно, одно из этих случаях относится к вашей проблеме.

person Reinhard Männer    schedule 29.07.2013
comment
Я думаю, что второй вариант, о котором вы сказали, может иметь место. Хотя я явно не создавал никаких дополнительных потоков, иногда, когда появляется ошибка lldb, я попадаю в представление, показывающее несколько одновременных потоков, я никогда не задумывался об этом, я думаю, что они автоматически создаются для более фундаментальных вещи уровня. Тем не менее, если это может быть так, как мне создать пул автоматического выпуска для потока, который я не создавал? - person Elbimio; 30.07.2013
comment
Это просто: просто поместите код потока в блок авторелиза @autoreleasepool {...ваш код...}, см. ‹developer.apple.com/library/ios/#documentation/cocoa/Conceptual/ - person Reinhard Männer; 30.07.2013
comment
Я не знаю, в какой части моего кода создается новый поток, как я уже сказал, я не вызываю какой-либо метод NSThread явно, я только полагаю, что у меня есть несколько потоков, потому что, когда я получаю ошибку lldb, отображаются несколько потоков. Как я могу сказать, где в моем коде будет находиться блок авторелиза? Я попробовал несколько из того, что сказано в документации, но, похоже, ничего не изменилось. Вот почему я хотел бы сузить до того, какой конкретный объект не освобождается. - person Elbimio; 31.07.2013
comment
Существует множество способов создания потоков. Наиболее распространенными являются вызовы PerformSelectorInBackground:, PerformSelector:withObject:afterDelay: и помещение чего-либо в очередь отправки системы Grand Central Dispatch. Если вы используете некоторые из них, в большинстве случаев необходимо заключить свой код в селектор блоком @autoreleasepool. - person Reinhard Männer; 31.07.2013
comment
Я пытаюсь найти окончательный список всех методов, которые создают отдельные потоки, чтобы узнать, использую ли я какой-либо из них. Кажется, я не могу найти ничего подобного, и я не вижу ничего очевидного в своем коде. - person Elbimio; 01.08.2013
comment
В большинстве случаев потоки создаются сообщениями типа PerformSelector (в фоновом режиме, после задержки и т. д.), объектами и блоками NSOperation (такими как блок завершения анимации или тот, который вы помещаете в операцию или очередь отправки). Подробности см. в документации ‹разработчику .apple.com/library/ios/#documentation/Cocoa/Conceptual/›. - person Reinhard Männer; 02.08.2013