我正在尝试在iOS5中同步以下代码:
>一个对象有一个方法,它从中产生一个HTTP请求
获取一些数据,包括图像的URL
>一旦数据到达,文本数据就用于填充
CoreData模型
>同时,第二个线程被调度异步下载
图片;此线程将通过KVO发送到viewController
该图像已经被缓存并在CoreData模型中可用.
>因为图像下载需要一段时间,我们立即返回
CoreData对象具有所有属性,但是对于图像
来电者
>另外,当第二个线程完成下载时,CoreData模型
可以保存.
这是(简化)代码:
- (void)insideSomeMethod { [SomeHTTPRequest withCompletionHandler: ^(id retrievedData) { if(!retrievedData) { handler(nil); } // Populate CoreData model with retrieved Data... dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0),^{ NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]]; aCoreDatanSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL]; }); handler(aCoreDatanSManagedObject); [self shouldCommitChangesToModel]; }]; } - (void)shouldCommitChangesToModel { dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,^{ NSError *error = nil; if(![managedObjectContext save:&error]) { // Handle error } }); }
但是发生的是基于屏障的保存块总是在图像加载块之前执行.那是,
dispatch_barrier_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,^{ NSError *error = nil; if(![managedObjectContext save:&error]) { // Handle error } });
之前执行:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,^{ NSURL* userImageURL = [NSURL URLWithString:[retrievedData valueForKey:@"imageURL"]]; aCoreDatanSManagedObject.profileImage = [NSData dataWithContentsOfURL:userImageURL]; });
所以显然我并不是真正在屏障之前调度图像加载块,否则屏障将等待图像加载块在执行之前完成(这是我的意图).
我究竟做错了什么?如何确保图像加载块在阻挡块之前排队?
解决方法
乍一看,问题可能是您正在全局并发队列上调度障碍块.您只能在自己的自定义并发队列中使用障碍块.根据dispatch_barrier_async上的GCD文档,如果将块分派到全局队列,它将表现为正常的dispatch_async调用.
Mike Ash在GCD屏障区有一个很好的博文:http://www.mikeash.com/pyblog/friday-qa-2011-10-14-whats-new-in-gcd.html
祝你好运
Ť