我有一个带有一个重功能的预构建的C
库(二进制文件和标头)。此功能可能需要分钟或更多才能完成。通常,我使用GCD在后台移动计算并保持UI线程免费:
// show activity indicator or something else
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
dispatch_async(queue, ^{
void *resultData = callOfHeavyLibraryMethodHere(params);
dispatch_async(dispatch_get_main_queue(), ^{
// show resultData to user
});
});
但是如果用户想取消此操作怎么办?众所周知,我无法停止GCD
中的运行块。我阅读了有关NSThread
的信息 - 但也无法从其他线程(Main)杀死一个线程(使用计算)。还有其他解决方案吗?
我无法使用此答案中的解决方案如何取消/退出/停止线程对象或在iOS中运行的线程,因为即使我调用cancel
方法,我也没有位置检查isCancelled
变量。
这不是我的情况:
NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation* myOp = [[NSBlockOperation alloc] init];
[myOp addExecutionBlock:^{
for (int i = 0; i < 1000000; i++)
{
if ([myOp isCancelled]) // <-- check and interrupt operation
return;
doSmallPartOfWorkForItemAtIndex(i);
}
}];
[myQueue addOperation:myOp];
这是我的情况:
NSOperationQueue* myQueue = [[NSOperationQueue alloc] init];
NSBlockOperation* myOp = [[NSBlockOperation alloc] init];
[myOp addExecutionBlock:^{
void *resultData = callOfHeavyLibraryMethodHere(params);
// pass data somewhere else
}];
[myQueue addOperation:myOp];
无法检查isCancelled
,并且操作不会以这种方式中断。我也无法打电话给[NSThread exit]
,因为我的代码中没有中间点。
调度队列的问题是,一旦派遣任务就无法取消任务。但是,您可以使用 NSOperationQueue
而是
NSOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
void *resultData = callOfHeavyLibraryMethodHere(params);
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// Main thread work (UI usually)
}];
}];
NSOperationQueue *queue = [NSOperationQueue new];
[queue addOperation:operation];
// you can cancel an operation like so
[operation cancel];
能够取消任务的能力是NSOperationQueue
比GCD的优势。另一个可能是在操作之间添加依赖项的可能性,这真的很方便。