Ios 在依赖于多个NSOperation对象的NSOperation对象中处理从多个NSOperation对象返回的数据

Ios 在依赖于多个NSOperation对象的NSOperation对象中处理从多个NSOperation对象返回的数据,ios,dependencies,asihttprequest,nsoperation,nsoperationqueue,Ios,Dependencies,Asihttprequest,Nsoperation,Nsoperationqueue,我正在编写一个web连接的应用程序,它需要执行几个异步请求,以加载依赖关系树中较低层所需的数据 图1. 为可视化目的,考虑一个ASIHTPREQUEST A、B、C、D、E和F:的例子。 A的url取决于B和C的结果 B的url取决于D、E和F的结果 B和C可以同时计算,D、E和F也可以同时计算 NSOperationQueue=[(D,E,F),(B,C),A] 到目前为止,我已经创建了一个NSOperationQueue,其中包含一个ASIHTTPRequests的依赖关系树。但是,AS

我正在编写一个web连接的应用程序,它需要执行几个异步请求,以加载依赖关系树中较低层所需的数据

图1.


为可视化目的,考虑一个ASIHTPREQUEST A、B、C、D、E和F:

的例子。 A的url取决于B和C的结果

B的url取决于D、E和F的结果

B和C可以同时计算,D、E和F也可以同时计算

NSOperationQueue=[(D,E,F),(B,C),A]


到目前为止,我已经创建了一个NSOperationQueue,其中包含一个ASIHTTPRequests的依赖关系树。但是,ASIHTTPRequests的URL应该取决于之前操作的结果,而现在,它们并不依赖于此

问题:将多个NSOperations执行的计算结果传递给依赖于它们的NSOperation的最佳方式是什么,我如何使用ASIHTTPRequests设置该方式

提前感谢,,
朱利安·塞皮克

我会做以下几件事

首先,请排队:

D、 E、F和C

在D、E和F的requestFinished委托回调中,检查其他所有3个请求是否已完成,如果已完成,则发送B

对B&C的回调执行相同的操作-如果它们都已完成,则发送A


您需要一种由所有请求共享的对象来将早期请求的结果/状态存储到中。

我最终解决了这个问题,将ASIHTTPRequest包装在一个自定义NSOperation对象中,该对象填充了请求,自定义请求B包含指向d,E,和F的ASIHTTPRequest用户信息字典。虽然我喜欢@JosephH的解决方案,但我不知道如何轻松地生成一个依赖关系树完好无损的字典或数组

下面提供了自定义NSOperationObject的简化版本;欢迎提出任何建议。我广泛使用它作为参考,但由于我之前没有任何扩展NSOperation类的经验,我确信有更好的方法来实现这一点

#import <Foundation/Foundation.h>
#import "SyncableData.h"
#import "ASIHTTPRequest.h"

@interface PushContentRequest : NSOperation <ASIHTTPRequestDelegate> {
    BOOL executing;
    BOOL finished;
    id <SyncableData> data;
    ASIHTTPRequest *request;
    NSURL *url;
    id <ASIHTTPRequestDelegate> delegate;
}

- (id)initWithDataObject:(id <SyncableData>)theData url:(NSURL *)theUrl delegate:(id <ASIHTTPRequestDelegate>)theDelegate;

@end


#import "PushContentRequest.h"

@implementation PushContentRequest

- (id)initWithDataObject:(id <SyncableData>)theData url:(NSURL *)theUrl delegate:(id <ASIHTTPRequestDelegate>)theDelegate {
    if ((self = [super init])) {
        executing = NO;
        finished = NO;
        data = [theData retain];
        url = [theUrl retain];
        delegate = [theDelegate retain];
    }
    return self;
}

- (BOOL)isConcurrent {
    return YES;
}

- (BOOL)isExecuting {
    return executing;
}

- (BOOL)isFinished {
    return finished;
}

- (void)start {
    if ([self isCancelled]) {
        [self willChangeValueForKey:@"isFinished"];
        finished = YES;
        [self didChangeValueForKey:@"isFinished"];
        return;
    }

    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    request = [ASIHTTPRequest requestWithURL:url];
    NSString *xmlToPost = [[NSString alloc] initWithString: [theData getXMLRep]];
    [request appendPostData:[xmlToPost dataUsingEncoding:NSUTF8StringEncoding]];
    [request setDelegate:self];
    NSDictionary *userInfoDict = [[NSDictionary alloc] initWithObjectsAndKeys:data, @"theData", nil];
    [request setUserInfo:userInfoDict];
    [userInfoDict release];
    [xmlToPost release];
    [self willChangeValueForKey:@"isExecuting"];
    [request start];
    executing = YES;
    [self didChangeValueForKey:@"isExecuting"];
    [pool release];

}

- (void)dealloc {
    [delegate release];
    [url release];
    [data release];
    [super dealloc];
}

- (void)requestFinished:(ASIHTTPRequest *)therequest {
    [delegate requestFinished:therequest];

    [self willChangeValueForKey:@"isFinished"];
    [self willChangeValueForKey:@"isExecuting"];

    executing = NO;
    finished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];
}

- (void)requestFailed:(ASIHTTPRequest *)therequest {
    [delegate requestFailed:therequest];
    [self willChangeValueForKey:@"isFinished"];
    [self willChangeValueForKey:@"isExecuting"];

    executing = NO;
    finished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];
}

@end
#导入
#导入“SyncableData.h”
#导入“ASIHTTPRequest.h”
@接口PushContentRequest:NSOperation{
布尔执行;
布尔完成;
id数据;
ASIHTTPRequest*请求;
NSURL*url;
id代表;
}
-(id)initWithDataObject:(id)数据url:(NSURL*)url委托:(id)数据门;
@结束
#导入“PushContentRequest.h”
@内容请求的实现
-(id)initWithDataObject:(id)数据url:(NSURL*)url委托:(id)数据门{
if((self=[super init])){
执行=否;
完成=否;
数据=[数据保留];
url=[theUrl retain];
委派=[委派保留];
}
回归自我;
}
-(BOOL)是并发的{
返回YES;
}
-(BOOL)执行{
返回执行;
}
-(BOOL)完成了{
返回完成;
}
-(无效)开始{
如果([自取消]){
[self-willChangeValueForKey:@“isFinished”];
完成=是;
[self-didChangeValueForKey:@“isFinished”];
返回;
}
NSAutoreleasePool*池=[[NSAutoreleasePool alloc]init];
请求=[AsiHttpRequestRequestWithURL:url];
NSString*xmlToPost=[[NSString alloc]initWithString:[theData getXMLRep]];
[请求appendPostData:[XmltoPostDataUsingEncoding:NSUTF8StringEncoding];
[请求setDelegate:self];
NSDictionary*userInfoDict=[[NSDictionary alloc]initWithObjectsAndKeys:data,@“theData”,nil];
[请求setUserInfo:userInfoDict];
[用户信息发布];
[xmlToPost发布];
[self Will ChangeValueForkey:@“isExecuting”];
[请求启动];
执行=是;
[self-didChangeValueForKey:@“正在执行”];
[池释放];
}
-(无效)解除锁定{
[授权释放];
[网址发布];
[数据发布];
[super dealoc];
}
-(void)请求已完成:(ASIHTTPRequest*)请求{
[委托请求已完成:请求];
[self-willChangeValueForKey:@“isFinished”];
[self Will ChangeValueForkey:@“isExecuting”];
执行=否;
完成=是;
[self-didChangeValueForKey:@“正在执行”];
[self-didChangeValueForKey:@“isFinished”];
}
-(void)请求失败:(ASIHTTPRequest*)请求{
[委托请求失败:请求];
[self-willChangeValueForKey:@“isFinished”];
[self Will ChangeValueForkey:@“isExecuting”];
执行=否;
完成=是;
[self-didChangeValueForKey:@“正在执行”];
[self-didChangeValueForKey:@“isFinished”];
}
@结束

此PushContentRequest的委托目前负责解释ASIHTTPRequest的UserInfo字典和我的实现中的请求,不过我认为在PushContentRequest的主体中进行此处理可能更有意义。

谢谢,@Joseph。我尝试过这个,但我不知道如何轻松地生成这个共享对象。正如我在中所解释的,我发现将NSOperation对象子类化为ASIHTTPRequest的包装器更容易。另外,我可能错了,但我认为您指的是D、E、F和B。鉴于队列自动执行其操作,将D、E和F排队,并将B从回调中的共享数据对象中拉出可能更有意义。