在父 NSOperation 上执行选择器

发布于 2024-09-01 04:01:49 字数 816 浏览 5 评论 0原文

我扩展了 NSOperation(称为 A),其中包含其他 NSOperations 的 NSOperationQueue(这是与 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

}

I extend NSOperation (call it A) which contains NSOperationQueue for other NSOperations (which is another extended class different from A, call these operations B). When operation A is running (executing B operations) how do i call a specific function/method on operation A when certain event takes place on B operations? For example every operation B that finishes it calls a function on operation A returning itself?

*Nested NSOperation and NSOperationQueue(s)

Hope this mockup pseudo code can help to draw the picture.

//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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千鲤 2024-09-08 04:01:49

NSOperation 有一种注册依赖项的机制。请参阅 NSOperation 文档addDependency:

让我们分开 A 所做的工作:AX:生成 B,以及 AY:收集 B 中的数据代码>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 中执行类似“Then”的操作,您可以

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

注意到,由于依赖关系,可以保证当 AY 运行时,所有 B 都已完成其操作。
这样,B 的实现就独立于A

NSOperation has a mechanism to register dependencies. See NSOperation's documentation and addDependency:.

Let's split the work your A does: AX: spawning Bs, and AY: collecting the data in B.
I think it's better to design B so that it can be used without A. Let B just download the data and hold it in the property data, as in

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

A doesn't have to have its own queue, one per object. Generating B's doesn't take much time either,
so AX doesn't have to be an operation.

So, I would just define the operations AY and B, prepare just one queue, and perform something like

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];
}

Then, in AY's main, you can

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

Note that, thanks to the dependencies, it's guaranteed that when AY is run, all of the B's has finished its operation.
This way, the implementation of B is independent of A.

昔日梦未散 2024-09-08 04:01:49

我已经编写了一个名为 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 的末尾运行某些内容,您可以向操作 A 添加完成块:

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

或者您可以在操作 A 中实现 -endError: (具体取决于您的方式)想要构建代码)。

请注意,此类是基于我创建的名为 MXCheckedOperation 的 NSOperation 子类构建的,该子类仅编码 NSOperations 的成功/失败和错误报告。

I've written a class called MXSuperOperation to nest NSOperations for the app I'm currently working on. I've posted it here:

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

Subclass MXSuperOperation and add suboperations in the -mainError: method.

@interface OperationA : MXSuperOperation

@end

@implementation OperationA

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

    return YES;
}

@end

Then to run something at the end of all the OperationBs, you can either add a completionBlock to operationA:

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

Or you can implement -endError: in OperationA (depending on how you want to structure the code).

Note that this class is built on an NSOperation subclass I made called MXCheckedOperation, which just codifies success/failure and error reporting for NSOperations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文