1

サーバーからいくつかの情報を同時にダウンロードしていますが、同じために NSOperatioQueue を使用しています。問題があります。たとえば、何らかの理由でダウンロード操作が失敗した場合、その操作をキューから削除したくありません。

現在、サーバーから応答が返されるとすぐに障害が発生した場合でも、操作はキューから削除されます。

特定の操作が論理的に終了しておらず、キューに保持する必要があることをキューに伝える方法はありますか?

私の場合、一連の情報をダウンロードしています。たとえば、郡内のすべての場所を取得してから、各郡のすべての家を取得します。そのため、ユーザーが有効なトークンでログインしていない場合、郡をダウンロードできない場合があります。その場合、サーバーは失敗メッセージを返します。ユーザーがアプリにログインしたときに再試行できるように、そのようなアイテムをキューに入れておきたいと思います。

サンプルコード

self.downloadQueue.maxConcurrentOperationCount = 1;
    for(Campaign *campaign in campaigns)
    {
        isContentUpdated = false;
        if(self.operation)
            self.operation = Nil;
        self.operation = [[DownloadOutlets alloc] initWithCampaign:campaign];
        [self.downloadQueue addOperation:operation];
    }

ここで、downloadQueue は NSOperationQueue であり、DownloadOutlets は NSOperation を拡張します。ありがとう

4

2 に答える 2

1

失敗した操作をキューに入れておくべきではありません。失敗した操作がタスクを実行しました。操作コントローラーに、またはその他の方法で操作の状態をリッスンさせ、completionBlock次に何をすべきかを決定する必要があります。操作が失敗したが、同様の操作を再試行する必要があると判断された場合は、別の操作を追加してタスクを再度実行する必要があります。

もう 1 つの方法は、成功するまでオペレーション内でダウンロードを再試行し、その後でオペレーションを終了することです。ただし、これは最適な設計ではありません。再試行するかどうかを決定したり、ユーザーに通知したりするために必要なすべての情報が操作に含まれていないためです。

于 2013-10-04T15:40:47.607 に答える
0

失敗した操作をキューに保持するべきではありませんが、シリアル フェッチ データにキューを使用し、操作が失敗した場合はキューイングを停止します。

@implementation DataAdapter
// ...

-(void)setup{
     // weak reference to self to avoid retain cycle
     __weak DataAdapter* selfRef= self;

     // create a block that will run inside the operation queue
     void(^pullCountriesBlock)(void)= ^{
           [[DownloadManager instance] fetchAllCountriesWithCompletionBlock:^(Result* result){
           if(result.successful){
                // on success
                [selfRef didFetchDataForAction:action];
           }else{
                // on failure
                [selfRef failedToFetchDataForAction:action];
           }
     };

     self.actions= [NSMutableArray new];
     [self.actions addObject:[DownloadAction actionWithBlock:pullCountriesBlock];
     // add other actions
     // ...
     [self fetchData];
}

}

-(void)fetchData{
     if(self.currentActionIndex >= self.actions.count){
           [self finishedFetchingData]; 
           return;
     }

     [self fetchDataForAction: self.actions[self.currentActionIndex] ];
}

-(void)fetchDataForAction:(DownloadAction*)action
      [self.myOperationQueueImplementation enqueueOperationWithBlock:action.block];
}

ダウンロードが成功した場合は、次のアクションをキューに入れるだけです (currentActionIndex をインクリメントして を呼び出しますfetchData)。失敗した場合は、それに応じて行動できます。私がすべきことは、最初に fetchData を呼び出す前に、興味深い NSNotificationCenter イベントのリッスンを開始することです。UserDidLogInNotification またはキューがダウンロードの実行を継続できるようにするその他のメッセージをリッスンできます。

于 2013-10-04T21:18:17.740 に答える