我有UIViewController
在viewDidLoad
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
items = [[DataFetcher sharedInstance] getItems handler:^(NSArray *currentItems){
if (currentItems.count % 30 == 0) { //don't wait for all the items to be ready show by chunks of 30
items = currentItems;
[tableView reloadData];
}
items = currentItems;
}];//Pretty complex call that takes some time to finish there is WebService calls, data parsing, storing some results ...
dispatch_async(dispatch_get_main_queue(), ^{
[tableView reloadData];
});
});
我需要做的是在弹出此viewController时停止getItems
。它毫无意义,需要CPU时间和精力(在某些情况下,此呼叫可能需要一分钟)。
我假设我应该在viewWillDisappear
中这样做,但究竟是怎么做的?
答案 0 :(得分:1)
您可以使用NSBlockOperation
。定期检查是否已取消,如果已经取消,则停止工作:
- (void)getItemsWithHandler:(void (^)(NSArray *currentItems))handler {
self.operation = [NSBlockOperation blockOperationWithBlock:^{
if (self.operation.isCancelled) {
return;
}
// Do something expensive
if (self.operation.isCancelled) {
return;
}
// Do something else expensive
for (int i = 0; i < 10000; i++) {
if (self.operation.isCancelled) {
return;
}
// Do expensive things in a loop
}
}];
}
- (void) cancelGetItemsRequest {
[self.operation cancel];
self.operation = nil;
}
或者,您可以在NSBlockOperation
中添加一堆NSOperationQueue
个。您可以设置工作的依赖关系,并根据需要立即取消整个队列。
答案 1 :(得分:0)
在NSOperation和NSOperationQueue中很好地支持取消异步操作,但它要复杂得多。在任何情况下,您的异步代码都必须不时检查它是否被取消或应该继续。
最好的办法是在某个地方“取消”某个属性,当你不想再做任何工作时设置,并且每当你尝试做更多的工作时,你都会检查该属性。