Objective-c 如何批量读取多个操作

Posted

技术标签:

【中文标题】Objective-c 如何批量读取多个操作【英文标题】:objective-c how to batch multiple read operations 【发布时间】:2014-08-17 13:32:53 【问题描述】:

我正在对存储在磁盘上的同一资源执行多个读取操作。

有时读取操作本身需要的时间比对同一资源的请求之间的时间要长。在这些情况下,将读取操作批处理到磁盘的一个读取请求中,然后将相同的结果返回给各个请求者是有意义的。

最初我尝试缓存初始获取资源请求的结果 - 但这不起作用,因为读取资源所花费的时间太长,并且有新请求进入 - 这意味着他们会尝试获取资源也是。

是否可以将额外的请求“附加”到已经在进行中的请求上?

我现在的代码遵循这个基本结构(这还不够好):

-(void)fileForKey:(NSString *)key completion:(void(^)(NSData *data) 
    NSData *data = [self.cache threadSafeObjectForKey:key];
    if (data) 
        // resource is cached - so return it - no need to read from the disk
        completion(data);
        return;
    
    // need to read the resource from disk
    dispatch_async(self.resourceFetchQueue, ^
        // this could happen multiple times for the same key - because it could take a long time to fetch the resource - all the completion handlers should wait for the resource that is fetched the first time
        NSData *fetchedData = [self fetchResourceForKey:key];
        [self.cache threadSafeSetObject:fetchedData forKey:key];
        dispatch_async(self.completionQueue, ^
            completion(fetchedData);
            return;
        );
    );

【问题讨论】:

【参考方案1】:

我想你想引入一个辅助对象

@interface CacheHelper
  @property (nonatomic, copy) NSData *data;
  @property (nonatomic, assign) dispatch_semaphore_t dataReadSemaphore;

你的 reader 方法现在变成了类似

CacheHelper *cacheHelper = [self.cache threadSafeObjectForKey:key]
if (cacheHelper && cacheHelper.data) 

   completion(cacheHelper.data);
   return;

if (cacheHelper)

   dispatch_semaphore_wait(cacheHelper.dataReadSemaphore, DISPATCH_TIME_FOREVER);
   dispatch_semaphore_signal(cacheHelper.dataReadSemaphore);
   completion(cacheHelper.data)
   return;

cacheHelper = [[CacheHelper alloc] init]
cacheHelper.dataReadSemaphore = dispatch_semaphore_create(0);
cacheHelper.data = [self fetchResourceForKey:key];
[self.cache threadSafeSetObject:cacheHelper forKey:key];
dispatch_semaphore_signal(cacheHelper.dataReadSemaphore);
completion(cacheHelper.data)

这是未编译的代码,所以请检查拼写和逻辑,但我希望它能解释这个想法。如果你想了解信号量,我喜欢这个post。

【讨论】:

这会阻塞缓存以进行其他操作(在不同的键上),所以我认为这不是一个好的选择 如果您不想阻塞 UI,可以将等待(if (cacheHelper) 中的部分)移至后台线程。

以上是关于Objective-c 如何批量读取多个操作的主要内容,如果未能解决你的问题,请参考以下文章

浅谈Swift 2中的Objective-C指针

将 Swift 类添加到具有多个目标的 Objective-C 项目

在 Objective-c 中使用 swift 类

如何从 Swift 调用 Objective-C 类的工厂方法?

如何在同一框架内访问 Objective-C 中的内部 Swift 类?

可互操作的 Obj-C typedef NS_ENUM 到 swift