ARC __bridge 强制转换 Block_copy 和 Block_release

2023-12-04

由于某种原因,我希望在运行循环的下一次迭代期间执行一个块,所以我想出了:

typedef void (^resizer_t)() ;

- (void) applyResizer: (resizer_t) resizer {
    resizer() ;
    Block_release(resizer) ;
}

- (void) usage {
    ...
    resizer_t resizer = ^() {
        // stuff
    } ;

    [self performSelectorOnMainThread:@selector(applyResizer:)
                           withObject:(__bridge id) Block_copy((__bridge void *) resizer)
                        waitUntilDone:NO] ;
}
  1. 我必须将参数强制转换为 void * ,这不是很讽刺吗Block_copy ?
  2. 为什么编译器在阻塞时对我的 Block_release 感到满意 在没有桥 void * 转换的 Block_copy 上?

该代码似乎有效,我没有检测到泄漏或过早发布,但我对语法有点困惑......


块被视为对象,因此 ARC 会阻止您将它们投射到void *没有明确的桥接演员。奇怪的是你的编译器没有抱怨Block_release:应该(在我的机器上,确实如此)。

因为 ARC 将块视为对象,所以您不需要使用Block_copy nor Block_release不再了。复制块(用-[NSObject copy])当您希望它移动到堆并让编译器管理剩余部分时。

-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]保留接收者和参数对象,直到调用该方法。所以你的区块将被保留并在需要时释放。您所要做的就是通过发送以下内容来确保该块没有存储在堆栈中copy在将消息传递给方法之前。

此外,还有一种更简单的方法来调度块的执行:它是 libdispatch(又名 GCD)。

dispatch_async(dispatch_get_main_queue(), resizer);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ARC __bridge 强制转换 Block_copy 和 Block_release 的相关文章

随机推荐