由于某些原因,我希望在run循环的下一次迭代中执行一个块,所以我想出了如下方法:
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] ;
}。
代码似乎有效,我没有发现泄漏,也没有早期发布,但我对语法感到有点困惑……
发布于 2012-03-14 12:59:27
块被视为对象,因此ARC阻止您在没有显式桥接强制转换的情况下将它们转换为void *。奇怪的是,您的编译器没有抱怨Block_release:它应该(在我的机器上)。
因为ARC将块视为对象,因此不需要再使用Block_copy或Block_release。当您希望该块移动到堆中并让编译器管理剩余部分时,请复制该块(使用-[NSObject copy])。
-[NSObject performSelectorOnMainThread:withObject:waitUntilDone:]保留接收方和参数对象,直到调用该方法为止。因此,您的块将保留,并在需要时释放。您所要做的就是确保块在传递给方法之前发送copy消息,而不是存储在堆栈上。
此外,还有一种更简单的方法来分派块的执行:它是lib分派(又名GCD)。
dispatch_async(dispatch_get_main_queue(), resizer);发布于 2012-03-14 13:05:23
我希望在运行循环的下一次迭代中执行一个块
这就是为什么你有dispatch_after。如果你提供一个很小的时间值,它就会产生你想要的效果:你给出一个块,当当前的运行循环完成并且重绘时刻已经发生时,这个块就会执行。
或者,如果您可以在不坚持块的情况下生存,请使用具有很小延迟值(甚至为零)的performSelector:withObject:afterDelay:。这也有同样的效果。
您所要求的是所谓的“延迟性能”,这是非常常见的。所以,按照框架给您的方式,这样做吧;不要像您的代码所做的那样,变得怪异和花哨。
https://stackoverflow.com/questions/9701923
复制相似问题