2010-05-11 41 views
1

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

*嵌套的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 

} 
+3

听起来令人费解和可怕。你想做什么? – 2010-05-11 23:38:21

+0

一些伪代码可能会使问题更清楚。 – 2010-05-11 23:46:51

+0

@Dave DeLong:这是一个编码实验。该应用程序需要一些指向服务器上的下载文件的URL。 NSOperation是为每个URL创建的,文件的大小是确定的并且分成块。从那里单独的NSOperation下载每个文件块。那有意义吗。 – MikeM 2010-05-12 01:20:58

回答

1

NSOperation有注册依赖性的机制。见NSOperation's documentation

让我们分裂的工作你A作用:AX:产卵B s和AY:收集在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

+0

不要以为这是我正在寻找的。由于对象A(它是NSOperation的扩展)产生许多其他对象B(它们也是NSOperation的扩展),并且对象B下载了一块文件,我希望每个对象B都联系它们的父对象A并告诉它们“嗨,我下载了这个文件的很多字节“(或任何其他消息)。 – MikeM 2010-05-12 16:45:33

+0

我建议将对象A的任务分解为AX:产生B和AY:从B中收集数据。我会相应地编辑我的答案。 – Yuji 2010-05-12 17:36:01

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年代末的东西,你可以一个completionBlock添加到运行a:

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

也可以实现在运行a(-endError:取决于你如何想构建代码)。

请注意,这个类是建立在一个名为MXCheckedOperation的NSOperation子类的基础之上的,它为NSOperations编写了成功/失败和错误报告。