Ответ 1
-
В терминах академического вопроса о том, кто "владеет" объектом, это просто тот, кто поддерживает ссылку
strong
на этот объект. -
С точки зрения обнаружения утечек в вашем приложении вы можете использовать инструмент "Утечки" в Инструментах, когда вы просматриваете приложение (выберите "Профиль" в меню "Продукт" Xcode).
-
Если он не появляется в "Утечках", похоже, вам тогда нужно решить, является ли он сильным эталонным циклом (ранее известным как цикл сохранения), некоторой простой логической ошибкой (например, некоторой круговой ссылаться на контроллеры, кэшировать большие объекты и т.д.) или некоторые проблемы, связанные с Core Foundation (ARC не принимает права собственности, если вы не будете осторожны с использованием
CFBridgingRelease()
или__bridge_transfer
). -
С точки зрения использования инструментов, чтобы найти источник распределений, два трюка, которые помогают мне больше всего:
- Перетащите мышью мышью (в версиях Xcode до 6 вы должны удерживать клавишу option, пока вы это делаете), чтобы выделить часть временной шкалы, чтобы определить, что вы хотите проверить. Вероятно, вы захотите сосредоточиться на одном из ваших пиков в распределении. Например, я нашел рельеф в своих выделениях и выделил его как таковой (это был просто смешной пример, когда я создаю огромный массив в
viewDidLoad
, но, надеюсь, он дает вам идею):
- Когда вы проверяете дерево вызовов, часто бывает полезно выбрать "Скрыть системные библиотеки", чтобы сосредоточиться на вашем коде. И если вы дважды щелкните по имени метода в "Инструменты" (в моем примере здесь будет
viewDidLoad
), тогда инструменты покажут ваш код, который выполняет выделение:
Затем вы можете дважды щелкнуть по соответствующему списку методов, и он приведет вас именно к коду, который сделал выделение.
- Перетащите мышью мышью (в версиях Xcode до 6 вы должны удерживать клавишу option, пока вы это делаете), чтобы выделить часть временной шкалы, чтобы определить, что вы хотите проверить. Вероятно, вы захотите сосредоточиться на одном из ваших пиков в распределении. Например, я нашел рельеф в своих выделениях и выделил его как таковой (это был просто смешной пример, когда я создаю огромный массив в
Пока это не показывает, что произошла утечка (т.е. где сильный ссылочный цикл или где вы его не выпустили), но такой анализ часто помогает вам отслеживать, где был создан экземпляр просочившегося объекта, который это первый шаг к устранению проблемы.
Если вам действительно нужно выяснить, кто "владеет" объектом (т.е. когда объект имеет сильные ссылки (или сохраняет)), Xcode 8 имеет новую функцию построения объекта. Поэтому отлаживаем приложение, а затем нажимаем значок "Debug Memory Graph" на панели отладки (круглая красная, внизу). Как только вы сделаете это, вы можете выбрать объект слева, и вы можете увидеть графический объект, который показывает утверждения о собственности на объект:
Вышеописанное показывает, что выбранное изображение имеет сильные ссылки как с UIImageView
, в котором оно представлено, но также ViewController также поддерживает сильную ссылку.
В более ранних версиях Xcode профилируйте приложение, чтобы запустить его с помощью инструментов и выберите опцию "Record reference counts" . В Xcode 6 это расположено на вкладке "Настройки записи" в правой панели:
В Xcode 5 и ранее вам нужно щелкнуть по кнопке info рядом с инструментом Allocations, чтобы увидеть эту опцию "Record reference counts" :
В любом случае, вы можете перейти в Сводку распределения, сверлить на какой-то объект, который не был выпущен (щелкнув стрелку вправо рядом с адресом объекта при просмотре и объекте в инструменте Allocations) и то вы увидите список сохранений и выпусков для рассматриваемого объекта, как показано выше. Но это только будет снято, если вы выберете "Счет ссылок на запись" перед профилированием приложения.
Требуется некоторое время, чтобы привыкнуть к отслеживанию учетных записей таким образом, но если вам абсолютно необходимо знать, где были установлены сильные ссылки, опция "Record reference counts" может помочь вам.