【问题标题】:Method with blocks inside NSOperation - how does it work?NSOperation 中带有块的方法 - 它是如何工作的?
【发布时间】:2012-03-30 22:40:38
【问题描述】:

我正在开发一个必须从 iOS4 运行的 iOS 项目。我有一个 NSOperationQueue 并添加了一个操作。操作的主要方法如下所示:

-(void)main 
{
    [self.client getStuffSuccess:^(Stuff *s) {
        //Do something on success
    } failure:^(NSError *error) {
        //Do something on failure
    }
}

block里面的代码只有在getStuff调用成功或者失败时才会被调用。我认为与此同时,我的操作将从 NSOperationQueue 中删除,并且不会调用该块。但是,我对其进行了测试,并且实际上调用了该块。无论客户端是在 dispatch_get_main_queue 上还是在调用它的线程上调用成功块,都会调用它——在本例中为上述操作。

在调用块之前,方法 isFinished 实际上返回 true(我覆盖了 isFinished 方法并检查了值),所以有人可以解释一下如何调用块吗?

我之所以问这一切,是因为虽然这对于一次调用来说很好,但当我在几百次迭代的循环中添加它时,我会得到一个 EXC_BAD_ACCESS,理解上述内容可能会帮助我进行调试。

【问题讨论】:

  • getStuffSuccess:failure 是同步的还是异步的?

标签: objective-c ios objective-c-blocks nsoperation nsoperationqueue


【解决方案1】:

block里面的代码只有在getStuff调用成功或者失败的时候才会被调用。我想同时,我的操作将从 NSOperationQueue 中删除,并且不会调用该块。

是什么让你相信这一点。块是一个闭包,一个自包含的代码块。它不依赖于某个其他对象(在这种情况下为 NSOperation)的存在才能存在。您可能希望它依赖于其他对象,但这取决于您执行。理想情况下,我会让 getStufSuccess:failure: 同步。如果你不能,你可以使用 NSCondition 或调用 NSRunLoop 方法来廉价地阻塞线程,直到它完成。

您还需要在这里考虑线程安全。您的问题可能与操作消失无关,但您的块做的事情不是线程安全的。

【讨论】:

    【解决方案2】:

    由于 getStuffSuccess:failure 是异步的,所以需要使用并发操作。这是一篇有用的博客文章: http://www.dribin.org/dave/blog/archives/2009/05/05/concurrent_operations/

    【讨论】:

      【解决方案3】:

      如果您的-getStuffSuccess:failure 没有阻塞线程(即该方法是异步的),那么您的-main 将完成并且您的 operationQueue 可能会在调用成功或失败块之前解除分配您的操作。您可以通过添加一个来阻止线程:

      while(notProcessed){
          sleep(0.1);
          //Make sure your success and failure functions update notProcessed BOOL
      }
      

      这样main 在您有机会调用闭包之前永远不会完成。或者只是使用同步方法。这通常很好,因为无论如何您都不会在 UI 线程上。

      【讨论】:

      • 在这种情况下,您需要使用并发操作(使用 -start 方法,而不是 -main,以及其他一些 KVO 的东西......见我上面的回复)
      • 酷,谢谢。如果这是问题所在,jsd 的答案提供了一个更正确、非黑客的解决方案。另外:asynchronous-methods-in-nsoperation
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-09-02
      • 2015-07-27
      • 1970-01-01
      • 1970-01-01
      • 2014-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多