繁体   English   中英

NSOperation和NSOperationQueue

[英]NSOperation and NSOperationQueue

我正在同时从服务器下载一些信息,并且我正在使用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。 谢谢

您不应将失败的操作排在队列中。 失败的操作已执行其任务。 您应该让操作控制器通过completionBlock或其他方式监听操作的状态,然后决定下一步要做什么。 如果确定操作已失败,但应重试类似的操作,则应添加另一个操作以再次执行任务。

另一种方法是在操作中重试下载,直到成功,然后才结束操作。 但是,这不是最佳设计,因为该操作没有而且不应该拥有决定是否重试,通知用户等所需的所有信息。

您不应将失败的操作保留在队列中,而应将队列用于串行获取数据,并在操作失败时停止排队:

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

如果下载成功,则将下一个动作fetchData (增加fetchData并调用fetchData )。 如果失败,则可以采取相应措施。 我要做的是在第一次调用fetchData之前开始侦听有趣的NSNotificationCenter事件。 您可以听UserDidLogInNotification或任何其他可能使队列继续运行下载的事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM