TheKitchenSync 1.0.3

TheKitchenSync 1.0.3

测试测试过
Lang语言 Obj-CObjective C
许可证 自定义
发布最后发布2014年12月

Aaron Sarazan维护。



  • Aaron Sarazan和Robby Walker

用于iOS并发的工具套件

Cue的iOS并发库TheKitchenSync为您提供了类似于Java中的高级锁和线程安全集合,方便您使用。

安装

您可以在5分钟内将TheKitchenSync集成到项目中:步骤详情。然后只需#import "TheKitchenSync.h"即可开始使用!

集合

Cue的线程安全数组类和字典类,支持所有基本的数组操作和字典操作,以及新的索引运算符

CueSyncArray *syncArray = [@[@"some", @"items"] cueConcurrent];
CueSyncDictionary *syncDict = [@{ @"key" : @"val" } cueConcurrent];
[self cuePerformBlockInBackground:^{
  [syncArray insertObject:@"more" atIndex:1];
  syncDict[@"key2"] = @"val2";
}];

int i = 0;

// We cannot guarantee safety during normal for-loops, but foreach loops are safe.
for (id obj in syncArray) {
  // Since we copy the array before enumerating, you can even mutate mid-loop!
  syncArray[i++] = @"I've been mutated!";
}

CueTaskQueue

CueTaskQueue在概念上类似于dispatch queue,但提供了更多控制。例如,它显式地维护一个用户可配置的线程数用于执行。此外,它允许客户端设置委托来实现自定义的任务去重逻辑。

CueTaskQueue *queue = [[CueTaskQueue alloc] initWithName:@"PewPewQueue"];

// relatively low-priority queue.
queue.threadPriority = 0.3; 

// single-thread so you don't have to worry about @synchronizing everything.
[queue startWithThreadCount:1]; 

for (int i = 0; i < 10; ++i) {
  [queue addTask:[CueBlockTask taskWithKey:@(i) priority:1.0f executionBlock:^(CueTask *task) {
    NSLog(@"Task %d reporting for duty!", i);
  }]];
}

// Cleans up and removes the thread.
[queue finish]; 

CueLoadingCache 和 CueLRUCache

类似于Guava MapMaker,CueLoadingCache 和 CueLRUCache是线程安全容器,可以通过键编程生成值。只需将加载块传递给任一对象,它将对传递给它的每个键应用该块。

// This cache object takes a filename as its key, and returns its NSData from disk.
CueLoadingCache *fileLoader = [[CueLoadingCache alloc] initWithLoader:^id(id key) {
  NSArray * paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
  NSString * docPath = [paths[0] stringByAppendingFormat:@"/%@",path];
  return [NSData dataWithContentsOfFile:docPath];
} isMemorySensitive:YES];

// Loads from disk the first time...
NSData *valueFirstTime = fileLoader[@"TextFile1.txt"];
// Loads from cache the second time.
NSData *valueSecondTime = fileLoader[@"TextFile1.txt"];

对于更复杂的锁定方案,TheKitchenSync提供CueFairLock,以及一个CueReadWriteLock。虽然在基准测试中,CueReadWriteLock比普通的或递归锁要慢得多。我们正在努力改进它,但在此期间请仔细考虑是否需要承担这种开销。

还提供了CueStackLock,它使用栈分配来保证执行离开当前作用域时解锁。这有助于最小化忘记解锁的情况,并确保正确的异常清理。

- (BOOL)safeLockedQuery {
  // Guarantees lock until scope ends.
  CueStackLock(_lock);
  if ([self needsToBreak]) {
    return NO;
  }
  return [self potentialThrowQuery];  
}

在使用CueStackLock时,请确保compiling为Objective C++。通常这意味着将文件扩展名从.m更改为.mm

贡献

我们知道还有更多可以做的事情来构建出色的库,并发性问题也非常复杂!

我们总是很乐意接受 pulls requests!以下是一些可能的改进点

  • -[CueLRUCache loaderForKey] 中,可以通过对有序字典实现更细粒度的控制来提高读取时的锁定性能,或许可以使用链表实现,而不是使用 NSMutableArray。
  • 如果有人想要将 CueLoadingCache 和 CueLRUCache 之间的公共代码抽象出来,我们将永远感激不已!

许可证

版权 2013 TheKitchenSync 作者。

在 Apache 许可证下发布,见 LICENSE。