Подтвердить что ты не робот

Есть ли способ "найти тайну"?

Недавно я исправлял код. Был большой класс, который бы не освободил. Вам нужно будет ударить его 5 или 6 релизами, чтобы получить его dealloc.

Я внимательно просмотрел большой класс и в конце концов нашел различные вещи, которые нужно было освободить.

Это заставило меня подумать: просто должен быть какой-то действительно простой способ "найти" все сохраненные объекты на объекте. Я прав?

Итак, есть ли простой способ найти все сохраненные объекты на объекте? Есть ли кнопка в XCode или инструментах, о которых все знают?

Что вы делаете, когда не можете найти такую ​​тайну?

Итак, в юниверсе iOS, если кто-нибудь знает "Показывать, где все сохраненные данные появились на этом объекте" - спасибо!

P.S. Обратите внимание, что утечки нет, и этот вопрос полностью не связан с утечками. Объект просто "совершенно правильно" не будет выпускаться.


Позже..

Поистине поразительное решение от Fabio:

Фабио предоставил удивительное решение этой проблемы. В девяти словах, вот он:

-(id)retain
    {
    NSLog(@"%@", [NSThread callStackSymbols]);
    return ([super retain]);
    }

Это удивительно полезно во многих ситуациях и приводит ко многим другим полезным вещам. Вероятно, вы сохранили мне две человеко-недели работы в год, Фабио. Спасибо!

Кстати, если вы просто справляетесь с этим и боретесь с выходом, я видел, что обычно будет много фрагментов с участием "UINib instantiateWithOwner:". Похоже, что они придут на первое место, за ними последуют значительные куски.

4b9b3361

Ответ 1

Просто гадать... но вы можете перезаписать метод сохранения пользовательского вызова класса super и бросить хороший NSLog для печати стека вызовов.


Обновить с помощью фактического кода от Joe

-(id) retain {
NSLog(@"%@", [NSThread callStackSymbols]);
return ([super retain]);
}

Еще одна важная деталь: [NSThread callStackSymbols] возвращает NSArray из NSStrings, который может быть отфильтрован и использован для других целей. Например, в сложном и динамическом коде, чтобы проверить, правильно ли метод вызывает другой.

Примечание: В среде ARC вам нужно будет сначала добавить флаги -fno-objc-arc в компилятор, чтобы вы могли переопределить сохранение и вызов super.

Ответ 2

Инструменты могут отображать стек вызовов для каждого malloc, выпускать и сохранять для любого объекта Obj-C в приложении без необходимости изменения кода. Он работает, когда вы используете ARC, что не относится к решению от fabio.

Это действительно полезно для поиска сохранности этих загадок - например, когда объект просто не будет отменен, если это необходимо.

Вот как:

  • CMD + I (Продукт/Профиль)
  • Когда инструменты появляются, выберите "Выделения" (NOT Leaks).
  • Ваше приложение должно работать.
  • Делайте все, что заставляет вас скрывать вашу тайну.
  • Выберите инструмент "Выделение" на левой панели.
  • Нажмите CMD + 1 или выберите круг с волной в нем справа. В панели справа внизу отметьте опцию "Record reference counts". Это важно, или будут записаны только mallocs и frees.
  • В окне поиска в правом верхнем углу списка введите имя своего класса (например, BCMyObject).
  • Это фильтрует список "Статистика" , чтобы показать, сколько экземпляров вашего класса в настоящее время проживает. Столбец #Persistent показывает, сколько экземпляров живут.
  • Нажмите строку, а затем маленькую стрелку → рядом с именем класса. Вы увидите, что в панировочных сухарях отображается "Статистика" > "Сводка распределения" > "BCMyobject"
  • Это показывает вам все экземпляры указанного класса (и какие из них живут).
  • Выберите экземпляр и снова щелкните стрелку (на этот раз по адресу)
  • Теперь вы увидите "Статистика" > "Сводка распределения" > "BCMyObject > History: 0xADDRESS" в breadcrumps.
  • Это будет отображаться каждый раз, когда объект malloc'd сохраняется или освобождается.
  • Теперь на левой панели, где была опция "Record Reference Counts", нажмите значок, который выглядит как панель с прикрепленными к ней ящиками или нажмите CMD + 3.
  • Выберите одну из строк, и вы увидите полный стек вызовов, который привел к вызову.

Легко! (МОГ)

Ответ 3

Поместите контрольную точку на пользовательский класс "Сохранить

Вы можете установить символическую точку останова при сохранении, а затем установить ее на метод сохранения пользовательского класса. Проблема здесь в том, что сохранение - это метод на NSObject, поэтому при размещении точки останова вы получите выбор всех классов objective-c.

В этом случае было бы лучше перезаписать метод сохранения пользовательского класса вызовом super, поэтому он ничего не сделал бы, кроме как вы могли бы разместить в нем точку останова.

Используйте действие точки останова для регистрации вызывающего абонента

Чтобы добавить действие точки останова, дважды нажмите на синий маркер. Найдите точку останова в списке и нажмите кнопку + справа. Затем выберите Debugger command и добавьте в это поле команду GDB frame 1, которая покажет вам вызывающего абонента. Таким образом, вы сохраняете холодный журнал, и откуда они берутся. При регистрации релизов аналогичным образом вы можете проверить, что такое дополнительный выпуск.

Это все еще немного утомительно, но это лучшее, что я могу придумать.

Ответ 4

Инструменты и управление памятью - ваш друг. Утечки и зомби - два из самых ценных инструментов. Используйте их.

Продукт → Профиль (или Cmd-I)

Ответ 5

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

Часто используется стоп-каротаж (обычно я использую несколько точек останова с bt;continue), но это говорит только о функции, которая называется удержание, а не о "увеличенной картине" (например, вы можете "передать право собственности" с помощью [ivar2 release]; ivar2 = ivar1; ivar1 = nil;), Иногда это утечка UIKit, поэтому у вас нет исходного кода, и вам действительно нужно копать.

Если это не утечка, вызовите -release несколько раз и посмотрите, где он сработает!

Ответ 6

Попробуйте использовать "Сборка и анализ" в Xcode?

Это отлично подходит для того, чтобы получить доступ к нижней части объектов.