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

Как проверить счетчик ссылок в режиме ARC?

Я использовал для проверки того, что некоторые из моих переменных имели ожидаемый счет сохранения, используя [myVar retainCount] под отладчиком, особенно для var, у которого не было пользовательского dealloc.

Как вы это делаете в режиме ARC? Как вы гарантируете отсутствие утечек памяти?

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

Изображение, которое я делаю:

MyObj *myObj=[[MyObj alloc] init];

тогда я вызываю

[somethingElse doSomethingWithMyObj:myObj];

а затем я делаю

myObj=NULL;

Если моя программа работает нормально, я ожидаю, что myObj будет уничтожен, но похоже, что это не так...

Итак, как я могу отслеживать это, особенно если somethingElse не управляется мной?

Теперь о инструментах: кажется очень сложно запускать инструменты памяти на моем mac (с 5 мегабайтами) без перезагрузки mac и начать с нуля. Это действительно раздражает! Инструменты продолжают сбой даже до запуска программы, так же как есть альтернативное решение?

4b9b3361

Ответ 1

Вы можете использовать CFGetRetainCount с объектами Objective-C, даже в ARC:

NSLog(@"Retain count is %ld", CFGetRetainCount((__bridge CFTypeRef)myObject));

Это не, особенно полезно для отладки, по причинам, подробно описанным в другом месте. Если вам нужно понять, где объект будет сохранен и выпущен, ознакомьтесь с этим ответом за помощью с помощью инструмента Allocations.

Единственный случай, когда я обнаружил, что проверка количества удержания действительно полезен, - это метод dealloc, когда что-то сохраняет и автореализует освобожденный объект. Это приведет к сбою позже, когда пул авторезистов будет слит. Вы можете определить причину этого, проверив количество удержаний до и после каждого сообщения. Таким образом, я обнаружил, что метод observationInfo (который обычно используется только для отладки) сохраняет и автореализовывает self. Однако даже такую ​​проблему обычно можно решить, не изучая счетчик удержания, просто обернув все тело dealloc в блок @autoreleasepool.

Однако счет сохранения может быть использован, чтобы узнать о реализации некоторых классов. (Только для развлечения или любопытства! Никогда не полагайтесь на недокументированные детали реализации в производственном коде!)

Например, попробуйте сразу же в @autoreleasepool в main:

NSNumber *n0 = [[NSNumber alloc] initWithInt:0];
NSLog(@"0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef)n0));
// Prints 2 in my test

Итак, NSNumber вероятнее всего кэширует (или, по крайней мере, повторно использует) некоторые экземпляры. Но не другие:

n0 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n0 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n0));
// Prints 1 - I am the sole owner of this instance.  There could be weak
// or unretained references to it, but no other strong references.

NSNumber *n1 = [[NSNumber alloc] initWithInt:200];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints 1 again.  New instance with same value as prior instance.
// You could of course compare pointers to see that they are separate
// instances.

Вы даже можете обнаружить, что NSNumber возвращает singleton, если вы alloc, но не инициализируете:

n1 = [NSNumber alloc];
NSLog(@"n1 reference count = %ld", CFGetRetainCount((__bridge CFTypeRef) n1));
// Prints -1.

(Обратите внимание, что вы также можете узнать много деталей о NSNumber, посмотрев исходный код Core Foundation, который доступен в http://opensource.apple.com. Но кто знает, что вы можете найти, если вы посмотрите на сохранение количества объектов, которые не являются бесплатными для мостов с объектами в Core Foundation?)

Ответ 2

Нет. ARC управляет управлением памятью для вас и не позволяет вам называть keepCount, и даже если вы его видите, номер, который он возвращает, не имеет смысла для вас. Если вы хотите, чтобы вы делали профилирование памяти в Инструментах с помощью инструментов "Утечки и распределения". Это лучший способ посмотреть и посмотреть, как ваше приложение распределяет память и улавливает любое неправильное использование памяти там.

Ответ 4

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

Когда вы его разместите, нажмите стрелку раскрытия на экземпляре. Это приводит к просмотру истории для сохранения и отношения.

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

Instruments showing object history and callstack detail

Ответ 5

Я считаю, что единственный способ - профилировать ваше приложение с помощью инструмента Allocations. Вам нужно будет щелкнуть по информационному дескриптору ( "i" рядом с "Распределение в левой панели" ) и нажать "Записать количество ссылок". Затем вы можете профилировать свое приложение и выполнять поиск определенного класса, который вы хотите проверить. Оттуда вы можете найти счет сохранения в панели расширенной детали для каждого экземпляра класса.

Вы также можете сделать это с помощью утечек (так как я считаю это вариацией инструмента Allocations).

Ответ 6

Получить объект retainCount?

Вы можете просто сделать точку останова и ввести команду ниже, чтобы получить объект retainCount

po object.retainCount

Ответ 7

Нет. Apple заявляет, что вам не нужно, поскольку ARC будет обрабатывать ее для вас.

Ответ 8

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