Подтвердить что ты не робот

Ios хранить ^ блок в словаре или массиве?

Могу ли я хранить ^ блок в словаре или массиве?

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

- (^)(NSString *message){
    for (delegate in allDelegates)
    {
        delegate.handlerBlock(message);
    }
}

но могу ли я хранить блоки в коллекции?

4b9b3361

Ответ 1

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

[NSArray arrayWithObject: 
[[^{ NSLog(@"block 1"); } copy] autorelease],
[[^{ NSLog(@"block 2"); } copy] autorelease], nil]

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

  [NSArray arrayWithObject: 
    [^{ NSLog(@"block 1"); } copy],
    [^{ NSLog(@"block 2"); } copy], nil]

Ответ 2

Блоки отличаются тем, что их следует копировать в большинстве случаев, когда другие объекты должны быть сохранены. Как вы должны были прочитать это сейчас, это происходит из-за того, что блоки запускаются в стеке ( "блок стека" ) и действительны только в локальной области, где они были определены. Копирование блока стека дает вам блок кучи, и он будет иметь динамическое время жизни, например, обычные объекты. Копирование кучи кучи просто сохранит его, поэтому всегда правильно копировать блок, когда вам нужно его поддерживать дольше.

Теперь функции, которые принимают блок-аргумент, обычно берут на себя ответственность за копирование блоков по мере необходимости. Поэтому при передаче блока этим функциям вам не нужно ничего особенного. Однако в этом случае вы передаете свой блок в [NSArray arrayWithObject:], который принимает обычный аргумент объекта. Поскольку он не принимает блок-аргумент, он не знает, чтобы скопировать аргумент, поэтому он просто сохранит его. Поэтому, когда вы передаете блок методу, который принимает нормальный аргумент объекта, вам сначала нужно скопировать его.

Ответ 3

Вы найдете, как это сделать, если вы прочтете очень хорошую статью здесь. И обратите особое внимание на упомянутую там идиому "скопируйте их со стека".