Будет ли самоудерживаться внутри блока?

До/после вызова блока счетчик сохранения всегда равен 1. From документ блока Apple мы знаем, что файл self должен сохраняться. Может кто знает почему?

NSLog(@"Before block retain count: %d", [self retainCount]);    
void (^block)(void) = ^(void){
    UIImage* img = [UIImage imageNamed:@"hometown.png"];
    [self setImage:img];
    NSLog(@"After block retain count: %d", [self retainCount]);
};
block();

person joshualmf    schedule 14.12.2011    source источник


Ответы (2)


Во-первых, retainCount бесполезен. Не называйте это..

Блоки сохраняют захваченные объекты только при копировании блока. Таким образом, в этом примере self не будет сохранено в блоке.

person bbum    schedule 14.12.2011
comment
В документе просто сказано: в среде с подсчетом ссылок по умолчанию, когда вы ссылаетесь на объект Objective-C внутри блока, он сохраняется. Это верно, даже если вы просто ссылаетесь на переменную экземпляра объекта. Однако переменные объекта, помеченные модификатором типа хранения __block, не сохраняются. Яблочный документ меня сильно смутил. Спасибо, ббм. - person joshualmf; 15.12.2011
comment
Пожалуйста, сообщите об ошибке в документах тогда. Согласен - не совсем понятно. Следует более четко указать, что сохранение может происходить только тогда, когда блок копируется, а язык, окружающий переменные экземпляра, также немного отличается. - person bbum; 15.12.2011

Хорошо, я провел небольшое исследование, теперь все стало более ясно. во-первых, я не использовал @property в блоке 1, что означает, что когда я его устанавливаю, ничего не копируется, поэтому они не сохраняются, во-вторых, если мы делаем [блочное копирование], переменные будут сохранены, если мы не скопируем , блок указывает на адрес стека, скопируйте его в кучу, чтобы сделать его безопасным.

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

после использования блока мы можем установить его равным nil self.block = nil; чтобы освободить переменные и избежать цикла сохранения.

PS. метод прерывания цикла сохранения — использование __block id weakSelf = self; в блоке, значит переменные __block тоже не сохраняются.

person nickyu    schedule 16.08.2013