ARC __bridge强制转换Block_copy和Block_release

ver*_*rec 4 objective-c ios automatic-ref-counting

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

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] ;
}
Run Code Online (Sandbox Code Playgroud)
  1. 具有讽刺意味的是,我必须强制转换为Block _copy 的论据 ?
  2. 为什么编译器对我的Block_release感到满意,因为它在没有桥接器void*cast的情况下阻塞Block_copy?

代码似乎工作,我没有发现泄漏也没有过早发布,但我对语法有点困惑......

Nic*_*idt 13

块被视为对象,因此ARC会阻止您在void *没有显式桥接转换的情况下将它们转换为对象.奇怪的是你的编译器没有抱怨Block_release:它应该(在我的机器上,它确实).

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

-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]保留接收器和参数对象,直到调用该方法.因此,您的块将在需要时保留并释放.您所要做的就是通过在将copy消息传递给方法之前发送消息来确保该块不存储在堆栈中.

此外,有一种更简单的方法来分配块的执行:它是libdispatch(又名GCD).

dispatch_async(dispatch_get_main_queue(), resizer);
Run Code Online (Sandbox Code Playgroud)