繁体   English   中英

将块与dispatch_async一起使用

[英]Using blocks with dispatch_async

在目标C中尝试用块进行操作。我遇到了一个奇怪的问题。

在下面,我创建了一个块,并将该块提交给全局调度队列上的异步执行。 它没有为我打印任何内容。 当我用sync替换关键字async时,它可以正常工作并立即打印结果。

@implementation BlockTest
+(void) blocksTest{
__block int m = 0;
void (^__block myblock)(void);
myblock = ^(){
     NSLog(@"myblock %u ", ++m);
};
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"dispatch_async dispatch_get_global_queue");
    myblock();
});
}
@end

int main(int argc, const char * argv[])
{
[BlockTest blocksTest];
}

有人可以帮我解决这个问题吗?

您的程序将在块有机会运行之前退出。

dispatch_async()之类的异步调用的性质是,它可以返回并允许调用方继续进行,可能在提交的任务完成之前。 可能甚至还没有开始。

因此, +blocksTest返回到main()的调用站点。 main()一直到结尾(顺便说一句,没有返回值,这对non- void函数不利)。 main()返回时,整个过程退出。 在进程终止期间,GCD管理的所有队列,任务,工作线程等都被拆除。

该进程不会等待所有线程退出或变为空闲状态。

您可以通过在main() +blocksTest调用之后调用dispatch_main()来解决此问题。 但是,在那种情况下,除非提交某个在某个时候调用exit()的任务,否则程序永远不会终止。 例如,您可以将调用置于在+blocksTest创建的块内退出。

实际上,在这种情况下,因为任务将在后台线程而不是主线程上运行,所以任何延迟立即退出的操作都已足够。 例如,调用sleep()一秒钟即可。 您也可以将主运行循环运行一段时间。 没有任何时间可以保证足够有足够的时间使全局队列有机会运行您的任务以完成任务,但是实际上,这只需要一秒钟的时间。

如果没有安排输入源或计时器,则运行run循环退出的方法会很复杂。 因此,您必须安排一个伪造的源(例如NSPort )。 如您所知,如果您不对实际内容使用运行循环,则这是一种笨拙的方法。

因为当您使用dispatch_async时,该块可能已经开始执行,但尚未到达您打印的位置。 但是,如果使用dispatch_sync,则要确保在返回之前完成整个块的执行。 记住,dispatch_sync是主线程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM