Reputation: 2067
I'm initiating an asynch thread using grand central dispatch in objective-c using the following code:
dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{
}
For a very long time I was having trouble correctly exiting the IBAction that triggers this. I do a lot of the code in the main thread wrapped inside this GCD thread using this code:
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
}
What I originally tried to do was simply put the return; statement inside this mainQueue block. After a lot of fiddling I discovered that to break out of the IBAction that contains all this the return; needs to be in the GCD queue.
Why is this? I thought that return would exit methods regardless of where it is in the program. Also, is it even possible to exit from a nested queue call like this?
Upvotes: 1
Views: 271
Reputation: 90601
A block is similar to a function. It is a different context from the code which defines it. A return
statement within a block exits that block, not the method or function within which the block was defined. (If the block has a non-void
return type, the return
statement also gives the return value of the block.)
For example, consider:
void foo(void)
{
int (^block)(int, int) = ^int(int a, int b) { return a + b; }
printf("3 + 5 = %d\n", block(3, 5));
}
The return
statement in the block does not return from foo()
, it just returns from the block and gives the return value of the block. The block is like a little separate function except that its code is provided right in the middle of another function and it can capture local variables from the context of its definition.
Now, the block given to dispatch_async()
does not take arguments or return a value, but the flow control of the return
statement is the same. It returns from that block, not from the method or function containing the call to dispatch_async()
. In particular, since dispatch_async()
runs the block asynchronously, it is quite possible (even likely) that the block won't be run until well after the method or function that called dispatch_async()
has already exited.
Upvotes: 1