Приложение iOS с ARC, найдите, кто является владельцем объекта - программирование

Приложение iOS с ARC, найдите, кто является владельцем объекта

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

Но, похоже, я не вижу полный стек вызовов, поэтому я не знаю, кому принадлежит этот объект в конце. Мне кажется, что этот владелец каким-то образом не освобождает объект (или объект, которому принадлежит подозреваемый объект).

Может кто-нибудь дать мне подсказку о поиске владельца выделенного объекта?

Также обратите внимание, что объекты не помечены как "просочившиеся", а выделенные. Мне кажется, что объекты просачиваются, так как постоянно выделяются новые объекты.

Приветствуется любая дополнительная помощь в отношении того, как лучше всего действовать и находить предполагаемые утечки.

4b9b3361

Ответ 1

  • В терминах академического вопроса о том, кто "владеет" объектом, это просто тот, кто поддерживает ссылку strong на этот объект.

  • С точки зрения обнаружения утечек в вашем приложении вы можете использовать инструмент "Утечки" в Инструментах, когда вы просматриваете приложение (выберите "Профиль" в меню "Продукт" Xcode).

  • Если он не появляется в "Утечках", похоже, вам тогда нужно решить, является ли он сильным эталонным циклом (ранее известным как цикл сохранения), некоторой простой логической ошибкой (например, некоторой круговой ссылаться на контроллеры, кэшировать большие объекты и т.д.) или некоторые проблемы, связанные с Core Foundation (ARC не принимает права собственности, если вы не будете осторожны с использованием CFBridgingRelease() или __bridge_transfer).

  • С точки зрения использования инструментов, чтобы найти источник распределений, два трюка, которые помогают мне больше всего:

    • Перетащите мышью мышью (в версиях Xcode до 6 вы должны удерживать клавишу option, пока вы это делаете), чтобы выделить часть временной шкалы, чтобы определить, что вы хотите проверить. Вероятно, вы захотите сосредоточиться на одном из ваших пиков в распределении. Например, я нашел рельеф в своих выделениях и выделил его как таковой (это был просто смешной пример, когда я создаю огромный массив в viewDidLoad, но, надеюсь, он дает вам идею):

    enter image description here

    • Когда вы проверяете дерево вызовов, часто бывает полезно выбрать "Скрыть системные библиотеки", чтобы сосредоточиться на вашем коде. И если вы дважды щелкните по имени метода в "Инструменты" (в моем примере здесь будет viewDidLoad), тогда инструменты покажут ваш код, который выполняет выделение:

    enter image description here

    Затем вы можете дважды щелкнуть по соответствующему списку методов, и он приведет вас именно к коду, который сделал выделение.

    enter image description here

Пока это не показывает, что произошла утечка (т.е. где сильный ссылочный цикл или где вы его не выпустили), но такой анализ часто помогает вам отслеживать, где был создан экземпляр просочившегося объекта, который это первый шаг к устранению проблемы.


Если вам действительно нужно выяснить, кто "владеет" объектом (т.е. когда объект имеет сильные ссылки (или сохраняет)), Xcode 8 имеет новую функцию построения объекта. Поэтому отлаживаем приложение, а затем нажимаем значок "Debug Memory Graph" на панели отладки (круглая красная, внизу). Как только вы сделаете это, вы можете выбрать объект слева, и вы можете увидеть графический объект, который показывает утверждения о собственности на объект:

введите описание изображения здесь

Вышеописанное показывает, что выбранное изображение имеет сильные ссылки как с UIImageView, в котором оно представлено, но также ViewController также поддерживает сильную ссылку.

В более ранних версиях Xcode профилируйте приложение, чтобы запустить его с помощью инструментов и выберите опцию "Record reference counts" . В Xcode 6 это расположено на вкладке "Настройки записи" в правой панели:

enter image description here

В Xcode 5 и ранее вам нужно щелкнуть по кнопке i info рядом с инструментом Allocations, чтобы увидеть эту опцию "Record reference counts" :

enter image description here

В любом случае, вы можете перейти в Сводку распределения, сверлить на какой-то объект, который не был выпущен (щелкнув стрелку вправо arrow рядом с адресом объекта при просмотре и объекте в инструменте Allocations) и то вы увидите список сохранений и выпусков для рассматриваемого объекта, как показано выше. Но это только будет снято, если вы выберете "Счет ссылок на запись" перед профилированием приложения.

Требуется некоторое время, чтобы привыкнуть к отслеживанию учетных записей таким образом, но если вам абсолютно необходимо знать, где были установлены сильные ссылки, опция "Record reference counts" может помочь вам.