ARC __bridge强制转换Block_copy和Block_release
出于某种原因,我想在运行循环的下一次迭代期间执行一个块,所以我想出了:
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] ; }
- 具体而言,我必须强制转换为Block _copy的论点吗?
- 为什么编译器对我的Block_release感到满意,因为它在没有桥接器void * cast的情况下阻塞Block_copy?
代码似乎工作,我没有检测到泄漏也没有过早发布,但我对语法有点困惑……
块被视为对象,因此ARC会阻止您在没有显式桥接转换的情况下将它们转换为void *
。 奇怪的是你的编译器没有抱怨Block_release
:它应该(在我的机器上,它确实)。
因为ARC将块视为对象,所以不再需要使用Block_copy
或Block_release
。 当您希望它移动到堆并让编译器管理剩余部分时,复制该块(使用-[NSObject copy]
)。
-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]
保留接收者和参数对象,直到调用该方法。 因此,您的块将在需要时保留并释放。 您所要做的就是通过在copy
消息传递给方法之前发送copy
消息来确保该块不存储在堆栈中。
此外,有一种更简单的方法来分配块的执行:它是libdispatch(又名GCD)。
dispatch_async(dispatch_get_main_queue(), resizer);
我希望在运行循环的下一次迭代期间执行一个块
好吧,这就是你有dispatch_after
的原因。 如果你提供一个很小的时间值,它将具有你正在经历的效果:你给出一个块,并且当当前的runloop完成并且重绘时刻已经发生时块将执行。
或者,如果您可以在不坚持块的情况下生存,请使用performSelector:withObject:afterDelay:
具有微小的延迟值(甚至为零)。 这具有相同的效果。
你所要求的是“延迟表现”并且很常见。 所以这是常见的方式,框架给你的方式; 不要试图像你的代码那样变得奇怪和幻想。
- 按创builddatesorting文件 – iOS
- 用AVFoundation崩溃video捕获
- Authorize.net ios Sdk错误
- Restkit映射依赖关系
- UITableView与NSFetchedResultsController不会第二次加载
- UIScrollView添加UIViewController作为子视图? 与UIPageControl
- layoutAttributesForSupplementaryViewOfKind:atIndexPath:传入不正确的indexPath
- 拦截Objective-C在子类中委托消息
- 为什么设置整数时会发生EXC_BAD_ACCESS和SIGABRT?