我想以 justin 的选项“dispatch APIs”为例:
通过在专用串行队列上执行所有访问,可以确保对共享资源的并发访问是安全的,我们称之为“sync_queue”。
这个“sync_queue”很可能是一个类的私有队列,它的 ivars 是你想要修改的资源。
您现在可以定义读/写非原子属性,例如:
@propery (nonatomic) NSArray* array;
写访问可以实现如下所示:
- (void) setArray:(NSArray* newValue)
{
dispatch_async(sync_queue, ^{
_array = newValue;
});
}
请注意,写访问是异步的。
对属性的读取访问将按如下方式实现:
- (NSArray*) array:(NSArray* value)
{
if (dispatch_get_specific(SyncQueueID) == sync_queue_id)) {
return _array;
}
else {
__block NSArray* result = nil;
dispatch_sync(_sync_queue, ^{
result = _array;
});
return result;
}
}
与写访问不同,读访问需要是同步的。该方法还必须检查当前执行上下文是否已经是 sync_queue 或同步队列的子级或任何大子级 - 否则,读取访问将导致死锁。
为了识别当前执行上下文,我们将特定标识符与同步队列相关联,在创建它时使用函数dispatch_queue_set_specific() 。稍后我们使用dispatch_get_specific从当前队列或父队列或任何祖父队列中获取此标识符。如果它返回此特定标识符,则该方法正在同步队列上分别在子队列或任何大子队列上执行。如果这是真的,该方法会立即返回该值。否则,它会在同步队列上同步调度。
笔记:
如果 UIKit 将访问共享资源,则 sync_queue 应为主队列。