retainCount в блоках показывает экстренное поведение - PullRequest
1 голос
/ 08 марта 2011

Я получил этот код в классе:

- (void)cancel {
    if (_cancelBlock)
        _cancelBlock();
}
- (void)overrideCancelWithBlock:(void(^)(void))cancelBlock {
    [_cancelBlock release];
    NSLog(@"AsyncOperation-overrideCancelWithBlock-[cancelBlock retainCount]=%lu (before)", [cancelBlock retainCount]);
    _cancelBlock = [[cancelBlock copy] retain];
    NSLog(@"AsyncOperation-overrideCancelWithBlock-[_cancelBlock retainCount]=%lu (after)", [_cancelBlock retainCount]);
}

- (void)dealloc
{
    NSLog(@"AsyncOperation-dealloc-[_cancelBlock retainCount]=%lu (before)", [_cancelBlock retainCount]);
    [_cancelBlock release];
    NSLog(@"AsyncOperation-dealloc-[_cancelBlock retainCount]=%lu (after)", [_cancelBlock retainCount]);
    [super dealloc];
}

Выходные данные для этого NSLog ():

 AsyncOperation-overrideCancelWithBlock-[cancelBlock retainCount]=1 (before)
 AsyncOperation-overrideCancelWithBlock-[_cancelBlock retainCount]=1 (after)
 AsyncOperation-dealloc-[_cancelBlock retainCount]=1 (before)
 AsyncOperation-dealloc-[_cancelBlock retainCount]=1 (after) 

Документация для метода copy говоритthis:

Особые замечания

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

Итак.Таким образом, выходные данные NSLog () всегда показывают одно и то же значение для retainCount?

Ответы [ 2 ]

2 голосов
/ 08 марта 2011
_cancelBlock = [[cancelBlock copy] retain];

Это чрезмерно сохраняет блок;просто -копируй.

Поскольку блоки могут изменять форму во время выполнения в зависимости от предпринятых действий и изменять тип во время компиляции в зависимости от деталей реализации, различные классы блоков обычно воспринимают retainCount как бессмысленный генератор.В некоторых случаях это будет означать возвращение всегда 1.

Обратите внимание, что ноль retainCount является логической невозможностью во всех случаях.

2 голосов
/ 08 марта 2011

и документация для retainCount говорят об этом:

Важно : Этот метод обычно не имеет значения при отладке проблем управления памятью.Поскольку любое количество объектов каркаса могло сохранить объект для хранения ссылок на него, в то время как пулы автоматического выпуска могут содержать любое количество отложенных выпусков для объекта, маловероятно, что вы можете получить полезную информацию из этогометод.

Чтобы понять основные правила управления памятью, которые вы должны соблюдать, прочтите «Правила управления памятью».Для диагностики проблем управления памятью используйте подходящий инструмент:

Статический анализатор LLVM / Clang обычно может обнаружить проблемы с управлением памятью даже до запуска вашей программы.
Инструмент Object Alloc в приложении Instruments (см. ИнструментыРуководство пользователя) может отслеживать распределение и уничтожение объектов.
Shark (см. Руководство пользователя Shark) также профилирует распределение памяти (среди множества других аспектов вашей программы).

Чтобы ответить на ваш вопрос: Only appleможет знать, почему retainCount на данный момент таков, как есть.

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