首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSOperation和NSOperationQueue

NSOperation和NSOperationQueue
EN

Stack Overflow用户
提问于 2013-10-04 23:16:14
回答 2查看 731关注 0票数 1

我同时从服务器上下载了一些信息,我也在使用NSOperatioQueue做同样的事情。我有个问题。例如,如果下载操作由于某种原因而失败,我不想将该操作从队列中删除。

现在,即使它是一个失败,只要它从服务器得到响应,操作就会从队列中删除。

有没有办法告诉队列,某个特定的操作在逻辑上没有完成,它应该将其保留在队列中?

在我的例子中,我正在下载一组信息。例如,获取一个县的所有位置,然后获取每个县的所有房屋。因此,在某些情况下,如果用户没有使用有效的令牌登录,则无法下载县。在这种情况下,服务器会返回一条失败消息。我想保持这样的项目在队列中,以便我可以重试时,用户登录到应用程序。

示例代码

代码语言:javascript
复制
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。谢谢

EN

回答 2

Stack Overflow用户

发布于 2013-10-04 23:40:48

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

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

票数 1
EN

Stack Overflow用户

发布于 2013-10-05 05:18:18

不应将失败的操作放在队列中,而是使用队列来串行获取数据,如果操作失败,则停止排队:

代码语言:javascript
复制
@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或任何其他允许队列继续运行下载的命令。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19184837

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档