我正在为标准 C API 编写一个 Obj-C 包装器。我想用块替换 C 回调。
让我们想象一个 C API:
void my_async_function(void (* callback)(void *), void *udata);
Obj-C 包装器如下所示:
- (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
并且__bridge_transfer
在许多情况下运行良好,但在块上,它们会导致非常奇怪的行为。
myAsyncFunction 的汇编代码:根本没有保留(Xcode 4.4、ARC、O3)。
非常奇怪的是,以下核心生成了objc_retainBlock
我对 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);
}
我们可以称其为编译器的错误吗?如果不是,编译器遵循什么规则?
类似主题: