2

依存関係ツリーで必要なデータをロードするためにいくつかの非同期要求を実行する必要のあるWeb接続アプリケーションを作成しています。視覚化目的のためNSOperationオブジェクト内の複数のNSOperationオブジェクトから返されたデータの処理

図1


、ASIHTTPRequests A、B、C、D、E、およびFとの例を考える:

AのURLは、Bの結果に依存及びC、

及びBのURLは、D D、Eの結果に依存し、そしてF.

B及びCを同時に計算することができ、そうすることができASIHTTPRequestsの依存関係ツリーを含んE、およびF

NSOperationQueue = [(D、E、F)、(B、C)、A]これまでのところ、私はNSOperationQueue作成した


。ただし、ASIHTTPRequestsのURLは前の操作の結果に依存する必要がありますが、今はそうしていません。

質問:何それらに依存NSOperationに複数のNSOperationsによって実行される計算の結果を渡すための最良の方法です、そしてどのように私はASIHTTPRequestsでこれを設定することができますか?事前に

おかげで、 ジュリアンCeipekは

答えて

1

私は、カスタム要求BにD、E、およびFのASIHTTPRequest UserInfo Dictionaryのオブジェクトへのポインタが含まれているように、要求を設定したカスタムNSOperationオブジェクトにASIHTTPRequestをラップすることでこの問題を解決しました。 @ JosephHのソリューションが好きではありましたが、依存関係ツリーをそのまま使って辞書や配列を簡単に生成する方法を理解できませんでした。

私のカスタムNSOperationObjectの簡略版が以下に提供されています。どんな提案も大歓迎です。私はApple's Concurrency Programming Guideを参考にしましたが、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 

私はそれがPushContentRequestの体内にこの処理を行うにはより多くの意味をなすかもしれないと仮定しても、このPushContentRequestのデリゲートは現在、ASIHTTPRequestののUserInfo辞書の解釈と私の実装で要求を処理します。

1

私は、次の手順を実行します。その送信した場合、他のすべての3つの要求は、完了したかどうかを確認、E & F、DのためのrequestFinishedデリゲートのコールバックでは

D、E、FおよびC

:キューで開始する

B.

はB & C用のコールバックのために同じことを行います - 彼らは両方の完成をした場合、あなたは結果/状態を保存するために、すべての要求によって共有のオブジェクトのいくつかの種類が必要と思いA.に

を送信しますアールのへのリクエスト。

+0

ありがとう、@JosephH。私はこれを試しましたが、この共有オブジェクトを簡単に生成する方法を理解できませんでした。私は、NSOperationオブジェクトをASIHTTPRequestのラッパーとしてサブクラス化するのが簡単であることを発見しました。[リンク](http://stackoverflow.com/questions/7086550/handling-data-returned-from-multiple-nsoperation-objects-in- an-nsoperation-object/7095123#7095123)。また、間違っているかもしれませんが、D、E、F、_B_を意味すると思います。待ち行列が自動的に操作を実行すると、D、E、およびFをキューに入れ、コールバック内の共有データ・オブジェクトからBを引き出す方が適切な場合があります。 –

関連する問題