在父NSOperation上执行选择器

时间:2010-05-11 23:11:12

标签: objective-c cocoa nsoperation

我扩展了NSOperation(称之为A),其中包含NSOperationQueue用于其他NSOperations(这是另一个与A不同的扩展类,调用这些操作B)。当操作A正在运行(执行B操作)时,如果在B操作上发生某些事件,我如何在操作A上调用特定的功能/方法?例如,每个完成它的操作B都会在操作A上调用一个函数来返回它自己?

*嵌套的NSOperation和NSOperationQueue(s)

希望这个模拟伪代码可以帮助绘制图片。

//My classes extended from NSOperation

NSOperation ClassA

NSOperation ClassB

//MainApp

-(void)applicationDidFinishLaunching:(NSNotification *)aNotification {

    ClassA A1;

    ClassA A2;

    NSOperationQueue Queue;
    Queue AddOperation: A1;
    Queue AddOperation: A2;


}

//Main of ClassA

-(void)main {

     ClassB B1;

     ClassB B2;

     NSOperationQueue Queue;
     Queue AddOperation: B1;
     Queue AddOperation: B2;

}

//Main of ClassB

-(void)main {

   //Do some work and when done call selector on ClassA above

}

2 个答案:

答案 0 :(得分:1)

NSOperation有一种注册依赖关系的机制。请参阅NSOperation's documentation

让我们分割你A所做的工作:AX:产生BAY:收集B中的数据。 我认为最好设计B,以便可以在没有A的情况下使用它。让B只需下载数据并将其保存在属性data中,如

@interface B:NSOperation{
}
-initWithURL:(NSURL*)url atPosition:(NSUInteger)position;
@property (readonly)NSData* data;
@end;

A不必拥有自己的队列,每个对象一个。生成B也不需要花费太多时间, 所以AX不一定是一个操作。

所以,我只想定义操作AYB,只准备一个队列,并执行类似

的操作
NSOperationQueue* queue=...;
NSArray* urls = ... ;
for(NSURL* url in urls){
     AY* ay=[[AY alloc] init];
     for(chunks in url){
         B* b= an instance for B for the chunk in url
         [ay addDependency:b];
         [queue addOperation:b];
     } 
     [queue addOperation:ay];
}

然后,在AY的主要内容中,您可以

-main{
      NSArray*bs=[self dependencies];
      for(B*b in bs){
           NSData* data=b.data;
      }
}

请注意,由于依赖关系,保证在运行AY时,所有B都已完成其操作。 这样,B的实施与A无关。

答案 1 :(得分:0)

我写了一个名为MXSuperOperation的类来为我正在处理的应用程序嵌套NSOperations。我在这里发布了它:

https://gist.github.com/joerick/e4d2c99a2127715d9bc3

子类MXSuperOperation并在-mainError:方法中添加子操作。

@interface OperationA : MXSuperOperation

@end

@implementation OperationA

- (BOOL)mainError:(NSError **)error
{
    [self addSuboperation:[OperationB new]];
    [self addSuboperation:[OperationB new]];

    return YES;
}

@end

然后在所有OperationB的末尾运行一些东西,你可以向operationA添加一个completionBlock:

[operationA setCompletionBlockWithSuccess:^(id operation) {
    NSLog(@"success");
} failure:^(id operation, NSError *error) {
    NSLog(@"error %@", error);
}];

或者您可以在OperationA中实现-endError:(取决于您希望如何构建代码)。

请注意,这个类是基于我制作的名为MXCheckedOperation的NSOperation子类构建的,它只编写了NSOperations的成功/失败和错误报告。