Нахождение, кто имеет счет удержания к объекту - PullRequest
5 голосов
/ 25 февраля 2009

У меня есть UIViewController, у которого retainCount равен 3, когда я его создаю. Это возбуждает меня как ужасно неправильно. Каков наилучший способ выяснить, кто увеличил retainCount до 3? Я полагаю, что создание экземпляра объекта должно дать указатель 1, тогда я полагаю, что, возможно, помещая его в стек UINavigationController, можно увеличить его на единицу (хотя в этом нет уверенности?), Но третье ... загадка.

Ответы [ 4 ]

43 голосов
/ 25 февраля 2009

Адам прав, что вы не должны слишком беспокоиться о сохранении счета.

Но если у вас когда-нибудь возникнет законная необходимость разгадать такую ​​загадку, хорошим методом будет создание подкласса для затронутого класса, чтобы вы могли добавлять переопределения к методам управления памятью.

например. в подклассе UIViewController вы можете реализовать:

- (id) retain
{
    // Break here to see who is retaining me.
    return [super retain];
}
20 голосов
/ 25 февраля 2009

Никогда не полагайтесь на счет удержания напрямую. Случилось так, что в процессе инициализации некоторый фрагмент кода имеет retain ed и autorelease d объект. Поскольку вы не можете сказать, сколько раз объект был autorelease d, вы на самом деле не знаете, что такое счетчик real .

Сохранять значения следует только в качестве средства отладки, никогда в качестве потока управления программой.

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

8 голосов
/ 25 февраля 2009

Какой самый лучший способ выяснить, кто увеличил retainCount до 3?

Это приближается к проблеме под неправильным углом. Это будет вводить вас в заблуждение, а будет вводить вас в заблуждение (и, вероятно, прямо за) реальной проблемой, когда она действительно существует.

Лучше подумать о , которому принадлежит объект. Намереваетесь ли вы сохранить объект как значение одного из ваших собственных свойств? Если это так, то вы один из его владельцев. Если нет, то нет. Если вы передаете объект другому объекту для хранения в одном из его свойств, то этот другой объект также является владельцем.

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

  • «Это один из моих контролеров. Ему принадлежат корневые объекты моей модели и один или несколько видов [контроллеров]. ”
  • «Это вид. Ему принадлежат некоторые части моей модели. ”
  • «Это часть моей модели. Он владеет только примитивными объектами. ”
  • «Это еще одна часть моей модели. Ему принадлежат некоторые примитивные объекты и некоторые другие кусочки модели ».

Если у вас есть четкое представление о ваших правах собственности, то вы не можете записать утечку памяти, кроме как, забыв сообщение release или autorelease (которое может случиться с кем угодно), и вы почти конечно, не пишите циклическое удержание (два объекта, сохраняющие друг друга), кроме как сознательно и с обильными комментариями и # предупреждениями.

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


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

1 голос
/ 26 февраля 2009

Это не 100% -ное решение, но LLVM Clang Static Analyzer может оказать большую помощь в отслеживании неправильного ручного управления памятью. Между Static Analyzer и MallocDebug вы можете быстро стать профессионалом в отслеживании проблем с управлением памятью. Кстати, несмотря на то, что «Инструменты» - новая горячность, я считаю, что MallocDebug гораздо надежнее.

Статический анализатор LLVM Clang можно найти здесь: Статический анализатор LLVM / Clang

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...