Tornado and Grand Central Dispatch: a quick look
Tornado and Grand Central Dispatch: a quick look
Posted Sep 16, 2009 20:37 UTC (Wed) by wahern (subscriber, #37304)In reply to: Tornado and Grand Central Dispatch: a quick look by mgedmin
Parent article: Tornado and Grand Central Dispatch: a quick look
int i;
int *p = &i;
(void)(^block)(void) = ^{ *p = 0; }
I'm fairly certain (but you can read the documentation yourself), that such code is fine. I think you might be confusing (or rather, not distinguishing):
int *const p;
with
const int *p;
and/or
const int *const p;
The first is effectively what you get from the perspective of the Block's scope. Note also that, by default, the semantics of the Block's "closure" are copy-by-value, not by-reference. This is the reason for the read-only restriction. So that:
int i = 42;
(void)(^block)(void) = ^{ printf("%d", i); }
i = 7
printf("%d", i); // yields 7
block(); // yields 42
You'd get the expected result--both printing 7--with:
__block int i = 42;
But this is all explained, more-or-less, in Apple's documentation. What I'm still unclear of is how the run-time handles the collection of __block-storage objects. It uses some sort of reference counting on the Block objects, and the __block-storage objects are referenced by the Block, presumably. But how it manages to decrement the reference count, I'm not sure of. It might not do it at all, so that in order for a Block to remain valid outside of the scope it was defined in you have to use the API, i.e. Block_copy, etc.
