I'm writing an Obj-C wrapper to a standard C API. I would like to replace C callbacks by blocks.
Let imagine a C API:
void my_async_function(void (* callback)(void *), void *udata);
The Obj-C wrapper looks like this:
- (void)myAsyncFunction:(dispatch_block_t)block
{
void *udata = (__bridge_retained void *)block;
my_async_function(my_callback, udata);
}
void my_callback(void *udata)
{
dispatch_block_t block = (__bridge_transfer dispatch_block_t)udata;
block();
}
__bridge_retained
and __bridge_transfer
work well in many cases but on blocks, they result in a very strange behavior.
The assembly code of myAsyncFunction: has no retain at all (Xcode 4.4, ARC, O3).
What is very strange is that the following core, generates a objc_retainBlock
, what I expected for myAsyncFunction:
void *a_global_var;
- (void)myAsyncFunction2:(dispatch_block_t)block
{
void *udata = (__bridge_retained void *)block;
a_global_var = udata;
my_async_function(my_callback, udata);
}
Can we call that a bug of the compiler? If not, what rule the compiler is following?
Similar topics: