2009-12-30 77 views
7

我有一堂课。在这个类的内部,我将一个NSOperation传递给我的全局变量中的NSOperationQueue。NSOperation和NSOperationQueue回调

现在我的NSOperation完成了。我只是想知道它已经在我的课程中完成了,并且让操作将数据传递给了这个类。这通常如何完成?

回答

21

我使用委托模式 - 这是苹果开发者大会上各位推荐给我的方法。

脚手架:

  1. 设置一个协议MyOperationDelegatesetResult:(MyResultObject *) result方法。
  2. 有谁需要结果实现该协议。
  3. @property id<MyOperationDelegate> delegate;添加到您创建的NSOperation子类。

工作:

  1. 当你创建你的操作,但你排队之前,告诉它谁应该得到的结果。通常,这是创建操作的对象:[myOperation setDelegate: self];
  2. 在操作的主函数结束时,请致电[delegate setResult: myResultObject];将结果传递。
+0

它会和操作一样运行在同一个线程上吗? – Mel 2009-12-30 18:02:28

+1

是的,除非你使用performSelectorOnMainThread来指定。 – 2009-12-30 18:40:45

14

添加一个观察者,你的类侦听更改的NSOperation子类

[operation addObserver:self 
      forKeyPath:@"isFinished" 
       options:NSKeyValueObservingOptionNew 
       context:SOME_CONTEXT]; 

然后实现以下方法的isFinished价值,有它寻找上下文您注册为监听器。您可以通过访问方法/属性使您想要从NSOperation子类获取的数据可用。

- (void)observeValueForKeyPath:(NSString *)keyPath 
         ofObject:(id)object 
         change:(NSDictionary *)change 
         context:(void *)context 

检查瓯KVO Programming GuideConcurrency Programming Guide更多信息。

另外,请注意观察者将在与Operation相同的线程上接收,因此如果您想要处理UI,您可能需要在主线程上运行代码。

+1

我发现这是有问题的,因为线程问题。有时观察者不会被调用。我以这种方式得到了不稳定的行为... – akw 2012-12-30 22:57:10

+0

您是否尝试强制通知从主线程触发? – Rambatino 2014-12-04 05:02:53

14

另一种替代方法...如果您在操作完成时需要做一些工作,可以将该工作放在一个块中并使用依赖性。这非常简单,尤其是使用NSBlockOperation。你

NSOperationQueue* myQueue = [[NSOperationQueue alloc] init]; 

NSBlockOperation* myOp = [NSBlockOperation blockOperationWithBlock:^{ 
    // Do work 
}]; 

NSBlockOperation* myOp2 = [NSBlockOperation blockOperationWithBlock:^{ 
    // Do work 
}]; 

// My Op2 will only start when myOp is complete 
[myOp2 addDependency:myOp]; 

[myQueue addOperation:myOp]; 
[myQueue addOperation:myOp2]; 

也可以使用setCompletionBlock

[myOp setCompletionBlock:^{ 
    NSLog(@"MyOp completed"); 
}]; 
+0

我相信这是最干净的方法,因为您可以很好地分离操作,并且还可以重复使用它们。 – 2013-05-22 12:06:50

相关问题