2012-01-13 4 views
6

Я понимаю, что вы должны скопировать блоки, чтобы они могли встать после того, как кадр стека завершится. Но, как это применимо к стек, выделенные блоки, используемые в вложенном блоке, как показано в следующем примере кода:Должен ли я скопировать блок здесь?

- doSomethingFunkyThenCall:(void(^)(int someValue))callback 
{ 
    [[NSOperationQueue currentQueue] addOperationWithBlock:^{ 
     // ... do some work here, potentially nesting into further blocks ... 
     callback(result); 
    }]; 
} 

Очевидно, что кадр doSomethingFunkyThenCall: стек будет заканчиваться до обратного вызова выполняется, так что придется быть скопировано. Но произойдет ли это автоматически при вызове addOperationWithBlock: или мне нужно сделать это вручную?

ответ

0

Да, вы должны сделать callback = [[callback copy] autorelease]; в верхней части этого метода.

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

Источники:
http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html http://thirdcog.eu/pwcblocks/#objcblocks

EDIT: получается, что я не прав. @bbum указывает ниже, что Block_copy будет копировать рекурсивно, и поскольку addOperationWithBlock: копирует его блок, обратный вызов также копируется.

+9

Nope; нет необходимости копировать блок в этом случае. Когда будет скопирован блок, заключенный с 'addOperationWithBlock:' (который будет выполняться 'NSOperationQueue'), он скопирует инкапсулированный блок. – bbum

+0

Спасибо. Ты прав. http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Blocks/Articles/bxVariables.html#//apple_ref/doc/uid/TP40007502-CH6-SW1 – joerick

+0

Благодарим вас за участие! Я еще не видел этот абзац из этой ссылки: «Когда вы копируете блок, при необходимости копируются любые ссылки на другие блоки из этого блока - все дерево может быть скопировано (сверху). Если у вас есть блок-переменные и вы ссылаетесь на блок изнутри блока, этот блок будет скопирован ». –

3

Скорее всего, это произойдет автоматически. Принципы проектирования Cocoa подразумевают, что вы не отвечаете за объекты (их управление памятью, передача блоков [которые фактически реализованы как соответствующие объекты Objective-C] и т. Д.), Которые вы не создали. Таким образом, вы можете просто передать блок, который вы получили в качестве параметра, и время выполнения будет управлять им в соответствии с его потребностями.

Смежные вопросы