Should I copy the block here?

I understand that you must copy blocks so that they can get up after the exit of the stack frame. But how does this apply to blocks allocated by stacks that are used in a nested block, as in the following code example:

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

Obviously, the stack frame doSomethingFunkyThenCall: stop before the callback is executed, so it will need to be copied. But will this happen automatically when addOperationWithBlock: called addOperationWithBlock: or do I need to do this manually?

+6
source share
2 answers

Yes, you have to do callback = [[callback copy] autorelease]; at the top of this method.

Objects used in blocks are saved automatically, but sending hold to a stack block actually does nothing (because hold semantics require it to return a receiver), so it will disappear after we leave the frame in which it was created.

Sources:
http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html http://thirdcog.eu/pwcblocks/#objcblocks

EDIT: Turns out I'm wrong. @bbum indicates below that Block_copy will copy recursively, and since addOperationWithBlock: copies its block, the callback is also copied.

0
source

Most likely, this will happen automatically. Cocoa Design principles assume that you are not responsible for objects (their memory management, block transfer [which are actually implemented as proper Objective-C objects], etc.) that you have not created yet. That way, you can simply pass in the block you received as a parameter, and the runtime will control it according to its needs.

+3
source

Source: https://habr.com/ru/post/905943/


All Articles