objective-c - ARC __bridge cast Block_copy 和 Block_release

标签 objective-c ios automatic-ref-counting

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

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 * 的论点,这不是很讽刺吗? 阻止_copy ?
  2. 为什么编译器在阻塞时对我的 Block_release 很满意 在没有桥 void * cast 的 Block_copy 上?

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

最佳答案

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

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

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

此外,还有一种更简单的方法来分派(dispatch) block 的执行:它是 libdispatch(又名 GCD)。

dispatch_async(dispatch_get_main_queue(), resizer);

关于objective-c - ARC __bridge cast Block_copy 和 Block_release,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9701923/

相关文章:

ios - ARC 在使用 block 时不释放内存

iphone - ARC 下紧密循环中 UIKit 的内存管理

ios - Objective C 在滚动另一个 View 时关闭键盘 [UIScrollViewKeyboardDismissModeInteractive]

iphone - 我想在同一 View Controller 中同时使用选项卡栏和导航栏

ios - 什么时候是tableView :numberOfRowsInSection: called in UITableView?

iphone - 如果没有更好的代码检查方式,我该如何编写呢?

ios - 在 Phonegap 中获取当前 UIViewController

ios - ios 11 beta 7 的 UIKeyboardWillShowNotification 问题

ios - iPad + UIWebView + PresentModalViewController

ios - 为什么我的 NSNotificationObserver 在消息运行时被释放?