Reputation: 3
In order for blocks to work can retain the local variables they have to have access to stack frame.
Because the frame has to persist after the function has exited I assume that what the block deals with is a copy of the original stack frame.
Does the stack frame retain a block or does the block retain the stack frame?
Do queues retain the blocks that are in them?
Upvotes: 0
Views: 225
Reputation: 299295
Blocks do not retain a stack frame. Stack variables referenced by a block are referenced on the stack until the block is moved to the heap. At that time, any automatic variables are copied along with the block, and any __block
variables are copied to the heap.
See Blocks and Variables in Block Programming Topics for details.
Stack frames do not retain anything, and nothing retains stack frames. Stack frames can't "do" anything (they're just offsets into the stack). And there's nothing to retain (they're just offsets into the stack). Stack frames cannot survive the exiting of their scope.
Queues effectively retain blocks that are added to them (and blocks effectively retain their queue until they are executed). By "effectively" I just mean that "there is a strong reference that will prevent it from being destroyed." Whether this is actually implemented with a call to objc_retain
is an implementation detail.
EDIT: That last paragraph may confuse more than it illuminates. Calls to dispatch_async
actually "copy" the block, rather than retain it. But the term "copy" here is not quite the same as what it means for other objects. It really is referring to moving a block from the stack to the heap, and your interviewers are probably exploring the MRC issue that you do not retain blocks that you want to hold onto, you copy them. But in ARC this has moved under the covers, and it's better to think about it in terms of strong references, which is the point I was hoping to make. When you call dispatch_async, it automatically handles copying the block for you, and releasing the block when it is complete (this is documented behavior; see link; this is true for both MRC and ARC). So you don't have to maintain a separate reference to the block to keep it around while it is on the queue (that would be very inconvenient).
The fact that blocks also maintain a reference to the queue until they're executed is documented in dispatch_queue_create.
Upvotes: 2