我正在开发一个必须在iOS4上工作的iOS项目。我有一个NSOperationQueue,我添加了一个操作。操作的主要方法如下所示:
-(void)main
{
[self.client getStuffSuccess:^(Stuff *s) {
//Do something on success
} failure:^(NSError *error) {
//Do something on failure
}
}
只有在getStuff调用成功或失败时才会调用块内的代码。我认为同时,我的操作将从NSOperationQueue中删除,并且不会调用该块。但是,我测试了它,并且实际上调用了块。无论客户端是在调用dispatch_get_main_queue还是在调用它的线程上调用成功块,都会调用它 - 在这种情况下是上面的操作。
在调用块之前,方法isFinished实际上返回true(我覆盖了isFinished方法并检查了值),所以有人可以解释一下这个块是如何被调用的?
我问这一切是因为虽然这对于一次调用工作正常,但是当我在几百次迭代的循环中添加它时,我得到一个EXC_BAD_ACCESS并且理解上面的内容可能会帮助我进行调试。
答案 0 :(得分:1)
只有在getStuff调用成功或失败时才会调用块内的代码。我认为同时,我的操作将从NSOperationQueue中删除,并且不会调用该块。
是什么让你相信这一点。块是一个闭包,一个独立的代码块。它不依赖于某些其他对象(在本例中为NSOperation)的存在以便存在。您可能希望依赖于其他对象,但这取决于您执行。理想情况下,我会使getStufSuccess:失败:同步。如果你不能,你可以使用NSCondition或调用NSRunLoop方法来廉价地阻止线程,直到它完成。
您还需要在此处考虑线程安全性。你的问题可能与操作消失无关,但是你的块做了一些非线程安全的事情。
答案 1 :(得分:0)
如果您的-getStuffSuccess:failure
没有阻止该线程(即该方法是异步的),那么您的-main
将完成,您的operationQueue可能会在调用成功或失败块之前解除您的操作。您可以通过添加:
while(notProcessed){
sleep(0.1);
//Make sure your success and failure functions update notProcessed BOOL
}
这样main
永远不会在您有机会调用闭包之前完成。或者只使用同步方法。这通常很好,因为无论如何你都不会在UI线程上。
答案 2 :(得分:0)
由于getStuffSuccess:失败是异步的,因此您需要使用并发操作。这是一篇有用的博文: http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/