performSelector:withObject:afterDelay:不排队选择器

时间:2012-09-10 12:05:45

标签: ios objective-c grand-central-dispatch nsrunloop

我设置了一个块来在不同的队列上运行,并在延迟后调用另一个方法:

piemanQ = dispatch_queue_create(PIEMAN_QUEUE_NAME, NULL);
dispatch_async(piemanQ, ^{
    [self performSelector:@selector(sendReadyToPieman) withObject:nil afterDelay:1.0];
});

我希望在@selector(sendReadyToPieman)之后一秒钟开火,但没有任何反应。我已经阅读了performSelector:withObject:afterDelay:上的doco,它讨论了通过当前队列上的计时器添加的方法。我检查了当前队列运行循环模式,但它返回nil。

我确定我之前已经完成了这种代码,但我已经在两个不同的地方尝试过这种情况,但两种情况都没有运行。但如果我用dispatch_after(...)替换它,一切正常。

任何人都能解释一下吗?

2 个答案:

答案 0 :(得分:2)

我的猜测是:dispatch_async执行它所说的内容,它使以下内容运行异步。你排队你的选择器,然后块完成,整个异步的东西消失。当然包括排队的选择器。

为了使performSelector能够执行任何操作,线程需要处于活动状态,并且需要执行runloop。

答案 1 :(得分:2)

您应该将操作放在NSOperationQueue上:

NSOperationQueue *piemanQ = [[NSOperationQueue alloc] init];
piemanQ.name = @"some name";
[piemanQ addOperationWithBlock:^{
    [self performSelector:@selector(sendReadyToPieman) withObject:nil afterDelay:1.0];
}];

这是自动异步的。对于问题,最好使用Objective-C解决方案而不是C解决方案。