Означает ли отсутствие предупреждения, которое может привести к сохранению цикла, сильный эталонный цикл не будет создан?

В соответствии с переходом к примечаниям к выпуску ARC, при ссылке на себя внутри блока следует использовать слабые ссылки, чтобы избежать сильного цикла ссылки/сохранения:

MyViewController *myController = [[MyViewController alloc] init…];
// ...
MyViewController * __weak weakMyController = myController;
myController.completionHandler =  ^(NSInteger result) {
MyViewController *strongMyController = weakMyController;
if (strongMyController) {
    // ...
    [strongMyController dismissViewControllerAnimated:YES completion:nil];
    // ...
}
else {
    // Probably nothing...
}
};

Иногда я получаю предупреждение компилятора о том, что ссылка на себя в блоке может привести к циклу сохранения. Означает ли отсутствие предупреждения, что цикл сохранения не будет создан? Почему предупреждение квалифицируется как «вероятно» привести к циклу удержания?


person MaxGabriel    schedule 12.11.2012    source источник
comment
Я думаю, что использование слова вероятно связано с тем, что компилятор не может знать наверняка, будет ли создан цикл. Он использует только ссылку на себя внутри блока как эвристику, чтобы предположить, что цикл может быть создан.   -  person Anurag    schedule 12.11.2012


Ответы (1)


Означает ли отсутствие предупреждения, что цикл сохранения не будет создан?

Нет. Компилятор может определить определенные условия, при которых вы можете создать цикл сохранения, но он не может исключить возможность того, что вы можете его создать. В качестве примера рассмотрим следующий класс:

@interface MyClass : NSObject

@property (readwrite, strong) id myObject;

@end

и фрагмент кода в другом классе:

MyClass *one = [MyClass new];
MyClass *two = [MyClass new];

one.myObject = two;
two.myObject = one; // created a strong cycle...

Чтобы компилятор даже заметил этот простой цикл, требуется анализ потока по нескольким классам, и, как правило, эта проблема неразрешима компилятором (вы можете сканировать/определять создание циклов во время выполнения, ARC этого не делает).

Почему предупреждение квалифицируется как «вероятно» привести к циклу удержания?

Создание цикла само по себе не является неправильным или плохим. Цикл представляет собой проблему только в том случае, если он становится осиротевшим; то есть на него не ссылаются никакие живые ссылки, и только циклические ссылки заставляют объекты в цикле оставаться живыми.

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

person CRD    schedule 12.11.2012