共享资源访问+ UI更新的GCD模式? [英] GCD pattern for shared resource access + UI update?

查看:76
本文介绍了共享资源访问+ UI更新的GCD模式?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

人!我在我的应用程序中实现共享缓存。这个想法是在后台从Web获取缓存数据,然后用新检索的数据更新缓存和UI。诀窍当然是确保线程安全,因为主线程将持续使用缓存。我不想以任何方式修改缓存,而别人可能正在使用缓存。



我的理解是,使用@synchronized锁定对共享资源的访问是不是最优雅的方法在ObjectiveC由于它陷入内核,因此是相当迟钝。我继续阅读,使用GCD代替是一个伟大的选择(让我们现在忽略它的表兄弟NSOperation),我想知道一个好的模式,我的情况会是。以下是一些示例代码:

  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); 

//在后台线程中下载数据
dispatch_async(queue,^ {
CacheData * data = [Downloader getLatestData];

//使用下面的主线程数据
dispatch_sync(dispatch_get_main_queue(),^ {
[AppCache updateCache:data];
[[NSNotificationCenter defaultCenter] postNotificationName:@CacheUpdatedobject:nil] ;
});
});




  1. 这实际上是做我认为它做的,这是今天处理这种情况的最干净的方法吗?有一个博客帖子非常接近我在说什么,但我想和你仔细检查。

  2. 我认为只要我只访问共享的共享资源在同一个线程/队列(在我的情况下主要),只有更新UI在主,然后我将有效地实现线程安全。是否正确?

谢谢!

解决方案>

是的。
除了其他考虑,不考虑使用私有调度队列将读/写工作分流到主线程。

  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 = ... fetch data ...});
return data;
}

然后更新原始代码:

  dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); 

//在后台线程中下载数据
dispatch_async(queue,^ {
CacheData * data = [Downloader getLatestData];
** [AppCache updateCache:数据]; **

//使用主线程中下载的数据
dispatch_async(dispatch_get_main_queue(),^ {
[[NSNotificationCenter defaultCenter] postNotificationName:@CacheUpdated object:nil];
});
});


folks! I'm implementing a shared cache in my app. The idea is to get the cached data from the web in the background and then update the cache and the UI with the newly retrieved data. The trick is of course to ensure thread-safety, since the main thread will be continuously using the cache. I don't want to modify the cache in any fashion while someone else might be using it.

It's my understanding that using @synchronized to lock access to a shared resource is not the most elegant approach in ObjectiveC due to it trapping to the kernel and thus being rather sluggish. I keep reading that using GCD instead is a great alternative (let's ignore its cousin NSOperation for now), and I'd like to figure out what a good pattern for my situation would be. Here's some sample code:

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];
    });
});

  1. Would this actually do what I think it does, and if so, is this the cleanest approach as of today of handling this kind of situation? There's a blog post that's quite close to what I'm talking about, but I wanted to double-check with you as well.
  2. I'm thinking that as long as I only ever access shared the shared resource on the same thread/queue (main in my case) and only ever update UI on main, then I will effectively achieve thread-safety. Is that correct?

Thanks!

解决方案

Yes. Other considerations aside, instead of shunting read/write work onto the main thread consider using a private dispatch queue.

dispatch_queue_t readwritequeue;
readwritequeue = dispatch_queue_create("com.myApp.cacheAccessQueue", NULL);

Then update your AppCache class:

- (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;
}

Then update your original code:

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];
    });
});

这篇关于共享资源访问+ UI更新的GCD模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆