Там нет цикла сохранения. Когда литерал блока определен внутри метода, контекст, который может быть захвачен блоком, ограничен тем, что видно внутри этого метода. В вашем примере:
- (void)methodA {
__block MyClass *blockSelf = self;
[someObject block:^{
[blockSelf methodB];
}];
}
Блок буквальный, а именно:
^{
[blockSelf methodB];
}
может видеть следующее:
self
и _cmd
, которые являются скрытыми параметрами, доступными в каждом методе Objective-C. Если бы у -methodA
были формальные параметры, их мог бы видеть и литерал блока;
- Любые переменные области блока внутри блока функции / метода, то есть каждая локальная переменная внутри метода и видимая в точке, где определен литерал блока. В этом примере единственная локальная переменная внутри
-methodA
- это blockSelf
, которая, поскольку она __block
-квалифицирована, не сохраняется;
- Любые переменные области файла (или глобальные переменные).
Литерал блока не знает (и, в общем случае, не может знать) о том, что происходит внутри других функций / методов, поэтому любой контекст, доступный внутри вызываемых функций / методов, не фиксируется литералом блока. Вам нужно только побеспокоиться о методе, в котором определяется литерал блока.
Я использую соглашение Apple об использовании заглавных букв «Блок» при обращении к пробелам / лямбдам (т.е. ^{}
) и строчном блоке при обращении к блокам С (т. Е. {}
).