Блоки и самоопределение из вызываемого метода - PullRequest
9 голосов
/ 02 декабря 2011

Хорошо, поэтому я понимаю, как избежать self сохранения циклов с блоками, как насчет случаев, когда я отправляю сообщение самому себе из метода в блок, вложенный глубже в стек вызовов, как это:

- (void)methodA {
    __block MyClass *blockSelf = self;
    [someObject block:^{
        [blockSelf methodB];
    }];
}

- (void)methodB {
    ...
    [self methodC];
    ...
}

- (void)methodC {
}

В этом случае [blockSelf methodB] нормально, но отправка [self methodC] из methodB вызывает цикл сохранения или нет?Нигде не могу найти ответ ...

1 Ответ

8 голосов
/ 02 декабря 2011

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

- (void)methodA {
    __block MyClass *blockSelf = self;
    [someObject block:^{
        [blockSelf methodB];
    }];
}

Блок буквальный, а именно:

^{
    [blockSelf methodB];
}

может видеть следующее:

  1. self и _cmd, которые являются скрытыми параметрами, доступными в каждом методе Objective-C. Если бы у -methodA были формальные параметры, их мог бы видеть и литерал блока;
  2. Любые переменные области блока внутри блока функции / метода, то есть каждая локальная переменная внутри метода и видимая в точке, где определен литерал блока. В этом примере единственная локальная переменная внутри -methodA - это blockSelf, которая, поскольку она __block -квалифицирована, не сохраняется;
  3. Любые переменные области файла (или глобальные переменные).

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

Я использую соглашение Apple об использовании заглавных букв «Блок» при обращении к пробелам / лямбдам (т.е. ^{}) и строчном блоке при обращении к блокам С (т. Е. {}).

...