2

在我发货的 iPhone 应用程序中,我使用了一个dispatch_async没有问题的块。该应用程序检查网站的价格更新,解析HTML,相应地更新核心数据模型,然后刷新正在查看的表格。

然而,在我最新的应用程序中,我发现在价格更新过程正在运行时,我可以通过退出应用程序来使应用程序崩溃。在我看来,第一次和第二次用法之间的区别只是我从表中调用调度块refreshController(即tableViewController现在内置的拉动刷新机制)并且现在是 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];
        })
});
4

3 回答 3

2

该样板代码看起来毫无用处。

您创建一个串行队列。您在队列上分派一个块,它只在主队列上分派一个块。您还不如直接在主队列上分派。

于 2014-02-19T09:29:05.817 回答
2

尽管您有一个异步块,但您正在该块中的主线程上执行 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 的内容。

Apple Docs 中的 Grand Central Dispatch (GCD) 参考

GCD 教程

于 2014-02-19T09:31:50.817 回答
0

调度队列中没有明确规定取消。基本上,它将是一个semaphore.

NSOperationQueue(更高级别的抽象,但仍使用底层构建GCD)支持取消操作。您可以创建一系列 NSOperations 并将它们添加到 NSOperationQueue 中,然后cancelAllOperations在不需要完成时向队列发送消息。

有用的链接:

http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/

调度队列:如何判断它们是否正在运行以及如何停止它们

于 2014-02-19T09:27:36.550 回答