Управление памятью Objective C с блоками, ARC и не-ARC

Я уже давно пользуюсь блоками, но чувствую, что мне не хватает управления памятью как в среде ARC, так и в среде без ARC. Я чувствую, что более глубокое понимание заставит меня избавиться от многих утечек памяти.

AFNetworking - это мое основное использование блоков в конкретном приложении. Большую часть времени внутри обработчика завершения операции я делаю что-то вроде & quot; [self.myArray addObject] & quot ;.

В средах с поддержкой ARC и без ARC "self" будет сохранен в соответствии сэта статья от Apple.

Это означает, что всякий раз, когда вызывается блок завершения сетевой операции AFNetwork, self сохраняется внутри этого блока и освобождается, когда этот блок выходит из области видимости. Я считаю, что это относится как к АРК, так и к АРК. Я запустил как инструмент утечки, так и статический анализатор, чтобы обнаружить утечки памяти. Никто не показал ни одного.

Однако до недавнего времени я не наткнулся на предупреждение, которое не смог понять. Я использую ARC в этом конкретном примере.

У меня есть две переменные экземпляра, которые указывают на завершение и сбой сетевой операции

@property (nonatomic, readwrite, copy) SFCompletionBlock completionBlock;
@property (nonatomic, readwrite, copy) SFFailureBlock failureBlock;
@synthesize failureBlock = _failureBlock;
@synthesize operation = _operation;

Где-то в коде я делаю это:

[self.operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id
                                                    responseObject) {
NSError *error = [NSError errorWithDomain:@"com.test" code:100 userInfo:@{@"description": @"zero results"}];
            _failureBlock(error);
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"nothing");
        }];

XCode жалуется на строку, которая вызывает errorBlock, с сообщением «Capturing» self ». Сильно в этом блоке, вероятно, приведет к сохранению цикла. Я считаю, что Xcode прав: блок сбоя сохраняет себя, а self хранит свою собственную копию блока, поэтому ни один из них не будет освобожден.

Однако у меня есть следующие вопросы / наблюдения.

1) Если я изменю _failureBlock (ошибка) на «self.failureBlock (ошибка)» (без кавычек) компилятор перестает жаловаться. Это почему? Это утечка памяти, пропущенная компилятором?

2) В целом, какова лучшая практика для работы с блоками как в ARC, так и в средах без поддержки ARC при использованииblocks that are instance variables? Кажется, что в случае блоков завершения и сбоя в AFNetworking, эти два блокаnot переменные экземпляра, так что они, вероятно, не попадают в категорию циклов сохранения, которые я описал выше. Но при использовании блоков прогресса в AFNetworking, что можно сделать, чтобы избежать сохранения циклов, подобных приведенному выше?

Я хотел бы услышать мнения других людей о ARC и не-ARC с блоками и проблемами / решениями с управлением памятью. Я нахожу эти ситуации подверженными ошибкам, и я чувствую, что некоторое обсуждение этого необходимо, чтобы прояснить ситуацию.

Я не знаю, имеет ли это значение, но я использую Xcode 4.4 с последней версией LLVM.

Ответы на вопрос(2)

Ваш ответ на вопрос