我想为每个方法使用 NSOperation 执行一些网络方法,并将操作添加到在后台线程上设置的 NSOperationQueue,我希望 NSOperations 发生序列化。
创建 NSOperation 队列的调用会定期调用,每 30 秒使用 NSTimer。
这是到目前为止截取的代码:
NSTimer *timer;
NSOperationQueue *bgQueue;
- (void)startdDownloadLoop{
if (![self.timer isValid]){
self.bgQueue = [[NSOperationQueue alloc] init];
self.timer = [NSTimer scheduledTimerWithTimeInterval:30.0
target:self
selector:@selector(updateDB)
userInfo:nil
repeats:YES];
}
}
- (void)updateDB{
// Next code was removed since si similar to the call `[self.bgQueue cancelAllOperations];`, as @robinkunde suggested
// for (NSOperation *operation in [self.bgQueue operations]) {
// if (operation.isExecuting) {
// [operation cancel];
// }
// }
[self.bgQueue cancelAllOperations];
self.bgQueue = [[NSOperationQueue alloc] init];
self.bgQueue.maxConcurrentOperationCount = 1;
NSBlockOperation *blockOp1 = [NSBlockOperation blockOperationWithBlock:^{
[NetworkManager downloadCars];
}];
NSBlockOperation *blockOp2 = [NSBlockOperation blockOperationWithBlock:^{
[NetworkManager downloadPartsForAllCars];
}];
NSBlockOperation *blockOp3 = [NSBlockOperation blockOperationWithBlock:^{
[NetworkManager downloadEachPathSpecs];
}];
[self.bgQueue addOperation:blockOp1];
[self.bgQueue addOperation:blockOp2];
[self.bgQueue addOperation:blockOp3];
}
NetworkManager
方法是带有完成处理程序的 POST/GET 方法,在完成下载后,它们将日期保存在数据库中,然后使用通知更新 UI。
更新:
由于困惑,我想将我关于代码的实际问题作为休假发布:
1- 如果 NSOperationQueue
的执行是串行的?
2 - 如果当我调用[operation cancel]
时会停止操作的执行?
3 - 如果当我调用 cancelAllOperations
并重新初始化它是清除当前 NSOperationQueue
的正确方法吗?
最佳答案
1) 您可以将队列上的属性maxConcurrentOperationCount
设置为1,以确保串行执行。
2) 这只对操作设置了 isCancelled
属性。需要对此更改采取行动并将其自身移动到完成状态,以便可以将其从队列中删除。
至于您的具体示例:NSBlockOperation
在所有附加 block 都已返回时被视为已完成。这实际上意味着,除非对 NetworkManager 的调用是同步的,否则该 block 会立即返回,操作被视为已完成,并且队列将开始下一个操作。队列完全有可能在第一个网络操作完成之前完成。如果您想一次执行一个,这不是执行此操作的方法。
您可以使用同步网络操作,但仍然不允许您取消它们。
查看此答案:NSURLSession with NSBlockOperation and queues
3) 这与 2) 有关。 cancelAllOperations
所做的只是对所有操作设置 isCancelled
属性。在这些操作完成之前,队列将继续存在。在同一属性上创建新队列不会改变这一点。
关于ios - 如何使用 NSOperationQueue 和 NSOperation 在后台 Thread 使用 NSTimer 定期调用序列化下载任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37967509/