Ios хранить ^ блок в словаре или массиве?
Могу ли я хранить ^ блок в словаре или массиве?
Мне нужно прислушиваться к уведомлению сервера, которому я должен предоставить блок для обработки уведомления, а в моем проекте несколько контроллеров представления все хотят услышать уведомление, поэтому я создал общий диспетчер уведомлений, у которого есть свой собственный блок для обработки уведомления сервера и имеет массив делегатов, поэтому в блоке менеджера:
- (^)(NSString *message){
for (delegate in allDelegates)
{
delegate.handlerBlock(message);
}
}
но могу ли я хранить блоки в коллекции?
Ответы
Ответ 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
Вы найдете, как это сделать, если вы прочтете очень хорошую статью здесь. И обратите особое внимание на упомянутую там идиому "скопируйте их со стека".