人们!我正在我的应用程序中实现共享缓存。我们的想法是在后台从Web获取缓存数据,然后使用新检索的数据更新缓存和UI。诀窍当然是确保线程安全,因为主线程将持续使用缓存。我不想以任何方式修改缓存,而其他人可能正在使用它。
我的理解是,使用@synchronized锁定对共享资源的访问权限并不是ObjectiveC中最优雅的方法,因为它会捕获到内核,因此相当迟缓。我一直在阅读,使用GCD代替是一个很好的选择(让我们暂时忽略它的堂兄NSOperation),我想弄清楚我的情况会有什么好的模式。这是一些示例代码:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// download the data in a background thread
dispatch_async(queue, ^{
CacheData *data = [Downloader getLatestData];
// use the downloaded data in the main thread
dispatch_sync(dispatch_get_main_queue(), ^{
[AppCache updateCache:data];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CacheUpdated" object:nil];
});
});
谢谢!
答案 0 :(得分:1)
如果你问100位开发人员是最优雅的方式,你将获得至少100个不同的答案(可能更多!)
我所做的,以及对我有用的是,让单身人士课程进行图像管理。我使用Core Data,并直接在商店中保存缩略图,但在Core Data中使用文件系统和URL来获取“大”文件。核心数据设置为使用新的基于块的接口,因此它可以在自己管理的私有线程上完成所有工作。
可能的图像URLS在主线程上注册了标记。其他类可以请求该标记的图像。如果图像不存在,则返回nil,但是此类设置fetchingFlag,使用与NSURLConnection耦合的并发NSOperation来获取图像,当它获取它时,它使用接收到的图像数据在其线程上向单例发送消息,并且获取该消息的方法使用'[moc performBlock:...]'(无等待)来处理它。
当图像最终添加到存储库时,moc将使用接收到的图像标记在主队列上调度通知。想要图像的类可以监听这个,当它们得到它时(在主线程上),然后他们可以再次向moc询问图像,这显然就在那里。
答案 1 :(得分:1)
是。 除了其他考虑因素之外,考虑使用私有调度队列,而不是将读/写工作分流到主线程上。
dispatch_queue_t readwritequeue;
readwritequeue = dispatch_queue_create("com.myApp.cacheAccessQueue", NULL);
然后更新您的AppCache类:
- (void)updateCache:(id)data {
dispatch_sync(readwritequeue, ^{ ... code to set data ... });
}
- (id)fetchData:... {
__block id data = nil;
dispatch_sync(readwritequeue, ^{ data = ... code to fetch data ...});
return data;
}
然后更新您的原始代码:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// download the data in a background thread
dispatch_async(queue, ^{
CacheData *data = [Downloader getLatestData];
**[AppCache updateCache:data];**
// use the downloaded data in the main thread
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"CacheUpdated" object:nil];
});
});