在我的运送iPhone App中,我使用了dispatch_async
块没有问题。该应用程序检查网站的价格更新,解析HTML
,相应地更新核心数据模型,然后刷新正在查看的表。
在我最新的应用程序中,我发现在价格更新过程正在运行时,我可以通过关闭应用程序来崩溃应用程序。第一次和第二次使用之间的差异在我看来只是因为我从表refreshController
调用了调度块(即。tableViewController
现在内置的pull-to-refresh机制)现在这是iOS7。
有人可以告诉我dispatch_async
如何在已知条件下优雅地中止,例如希望停止流程的用户,或者他们切换这样的应用程序并且我想截取该活动来管理块好吗,拜托?
如果有任何关于积极做什么和不做的好背景阅读,我也很高兴看到这样的链接 - 谢谢!
这是我正在使用的(主要是样板文件)dispatch_async代码,为了您的方便:
priceData = [[NSMutableData alloc]init]; // priceData is declared in the header
priceURL = … // the price update URL
NSURL *requestedPriceURL = [[NSURL alloc]initWithString:[@“myPriceURL.com”]];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:requestedPriceURL];
dispatch_queue_t dispatchQueue = dispatch_queue_create("net.fudoshindesign.loot.priceUpdateDispatchQueue", NULL); //ie. my made-up queue name
dispatch_async(dispatchQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:urlRequest delegate:self startImmediately:YES];
[conn start];
})
});
答案 0 :(得分:2)
那个样板代码看起来很无用。
您创建一个串行队列。您在队列上调度一个块,除了在主队列上调度块之外什么都不做。您也可以直接在主队列上调度。
答案 1 :(得分:1)
虽然您有一个异步块但是您正在该块中的主线程上执行NSURLConnection请求,这就是为什么应用程序在进程未完成时崩溃的原因。在后台线程中执行请求。您正在阻止此代码中的主线程。
你可以这样做:
dispatch_queue_t dispatchQueue = dispatch_queue_create("net.fudoshindesign.loot.priceUpdateDispatchQueue", 0); //ie. your made-up queue name
dispatch_async(dispatchQueue, ^{
NSURLConnection *conn = [[NSURLConnection alloc]initWithRequest:urlRequest delegate:self startImmediately:YES];
[conn start];
...
//other code
...
dispatch_async(dispatch_get_main_queue(), ^{
//process completed. update UI or other tasks requiring main thread
});
});
尝试阅读并练习更多关于GCD的内容。
答案 2 :(得分:0)
在调度队列中有无显式提供取消。基本上,它将是semaphore
。
NSOperationQueue
(更高级别的抽象,但仍使用下面的GCD
构建)支持取消操作。您可以创建一系列NSOperations并将其添加到NSOperationQueue,然后在不需要它完成时将 cancelAllOperations
发送给队列。
有用的链接:
http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/
Dispatch queues: How to tell if they're running and how to stop them