3

RequestManager と呼ばれるシングルトン クラスを取得しました。これは、アプリケーションのさまざまなモジュールとバックグラウンド タスクによって行われた要求を処理します。

@interface RequestFactory : NSObject

- (void)requestDataWith:(NSString *)token
                     id:(NSString *)id
                 sender:(id<RequestFactoryDelegate>)sender;
...

@end

次に、リクエスト中にすべてのコールバックを処理する、SessionDelegate と呼ばれる別のクラスを取得しました。

@interface SessionDelegate : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>

@property (weak, nonatomic) id <RequestFactoryDelegate> delegate;

@end

CommonCrypto などで多くのヘルパー クラスが必要なため、これらのクラスに関数をカプセル化して、クラスが過負荷にならないようにするというのが私の考えです。

そこで、コード化されたプロトコル RequestFactoryDe​​legate をすばやく設定して、受信したデータをオリジン リクエストを開始した送信者に送信します。

- (void)requestDataWith:(NSString *)token
                     id:(NSString *)id
                 sender:(id<RequestFactoryDelegate>)sender
{
    self.sessionDelegate.delegate = sender;

    NSMutableURLRequest *request = //create the request here

    NSURLSessionDataTask *dataTask = [self.defaultSession dataTaskWithRequest:request];
   [dataTask resume];
}

ええと、オブジェクトがあれば機能します。リクエストを送信するそれをsenderAと呼びましょう。設定されたデリゲートは常にsenderA自体であるためです。

この問題は、別のオブジェクト、たとえば、senderB がリクエストを送信する場合に発生しますが、同時にではなく、senderA が送信した直後に発生します。

- (void)foo
{
    [requestFactory requestDataWith:token
                                 id:id
                             sender:senderA]; // let's assume this takes 20s

    [requestFactory requestDataWith:token
                                 id:id
                             sender:senderB]; // let's assume this takes 1s
 }

senderA のリクエストはまだ進行中なので、senderB はデリゲートを彼に設定し、senderB のデリゲート関数が 2 回実行されます。

 <senderB>
 <senderB>

ええと...私は本当に独自のカスタム デリゲートを実装する必要があります (RequestFactory と同じクラスであるかどうかに関係なく)、senderA または senderB に適切に応答できるようにコールバック メソッドを処理するにはどうすればよいですか?

私の最後のアイデアは、NSURLSessionTasks クラスをオーバーライドして、独自のデリゲート プロパティまたはブロック プロパティなどを実装することです。

よろしくお願いします。

4

3 に答える 3

10

任意のオブジェクトをタスクにアタッチできます。

NSMutableURLRequest* req = [NSMutableURLRequest requestWithURL:url];
id whatever = // anything at all!
[NSURLProtocol setProperty:whatever forKey:@"thing" inRequest:req];
NSURLSessionDownloadTask* task = [[self session] dataTaskWithRequest:req];

そして、後で (デリゲートで) 次のように取得します。

NSURLRequest* req = task.originalRequest;
id thing = [NSURLProtocol propertyForKey:@"thing" inRequest:req];

ここの値 ( whatever) は、任意のオブジェクトにすることができます。これは完了ハンドラーのコールバックである可能性があります - 私はこれを実行しましたが、問題なく動作します。

于 2013-11-14T17:48:04.567 に答える