在NSOperation中使用performSelector:withObject:afterDelay:

4
我正在执行一些代码,这些代码在由NSOperationQueue管理的NSOperation对象中。该代码还包含一个使用performSelector:withObject:afterDelay:进行的延迟方法调用。
问题是,应该被延迟调用的相应选择器根本没有被调用
阅读了StackOverflow问题的这个答案后,我猜测这是由于NSOperation已经完成并且其线程甚至不再存在,从而“忘记”调度选择器的原因。
如何解决这个问题?如何在NSOperation内部延迟调用方法?
1个回答

4

一种可能的方法是使用Grand Central Dispatch,即dispatch_after()

double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_after(popTime, queue, ^{
    ...
});

除了使用dispatch_get_global_queue(),你当然也可以创建自己的调度队列或使用主队列dispatch_get_main_queue()


由于我对NSOperationQueueGCD都是新手,所以有一个比较菜鸟的问题:我能否以某种方式将正在执行的当前NSOperationQueue用作具有延迟的GCD分派的调度队列? - fabb
上面的代码不能与dispatch_get_global_queue一起使用,但可以与dispatch_get_main_queue一起使用。有什么想法为什么会这样? - fabb
我对GCD的了解不是很深,因此我并不完全理解在GCD队列中排队对保留/释放过程的影响,但我的猜测是您最初的问题是由于NSOperation中的所有对象都被释放引起的。如果您搜索与在NSOperation中使用异步NSURLConnection相关的问题,您会看到一些解决方法,这些解决方法涉及维护指向对象的指针,以防止NSOperation完成。 - Rob Reuss
不同的是,你可以稍后取消 performSelector:withObject:afterDelay:,但你无法取消 dispatch_after() - user102008

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接