iOS自定义对象的读写怎么保证线程安全
2018-03-28 本文已影响8人
Eddiegooo
需求:这个对象有很多属性,时时刻刻读取和写入,并且保证线程安全
方案:用栏栅dispatch_barrier_async,重写get 和setter 方法。
<一>什么是dispatch_barrier_async函数
毫无疑问,dispatch_barrier_async函数的作用与barrier的意思相同,在进程管理中起到一个栅栏的作用,它等待所有位于barrier函数之前的操作执行完毕后执行,并且在barrier函数执行之后,barrier函数之后的操作才会得到执行,该函数需要同dispatch_queue_create函数生成的concurrent Dispatch Queue队列一起使用。
<二>dispatch_barrier_async函数的作用
1.实现高效率的数据库访问和文件访问;
2.避免数据竞争。
<三>栅栏函数中传入的参数队列必须是由 dispatch_queue_create 方法创建的队列,否则,与dispatch_async无异,起不到“栅栏”的作用了,对于dispatch_barrier_sync也是同理。
测试代码:
- (void)testQueue {
//串行队列 参数:DISPATCH_QUEUE_CONCURRENT 并行队列:DISPATCH_QUEUE_SERIAL
dispatch_queue_t queue = dispatch_queue_create("com.gcd.barrier.concurrentQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_sync(queue, ^{
sleep(3);
NSLog(@"3333");
});
dispatch_sync(queue, ^{
sleep(1);
NSLog(@"1111");
});
dispatch_barrier_async(queue, ^{
NSLog(@"Barrier async");
});
dispatch_sync(queue, ^{
[NSThread sleepForTimeInterval:2];
NSLog(@"44444");
});
}
输出结果:
![](https://img.haomeiwen.com/i2286585/33d8ab59de6c587f.png)
实现代码:
dispatch_queue_t _modelDataQ =dispatch_queue_create("somedesccriptions", DISPATCH_QUEUE_CONCURRENT);
//同步读取(一次一次读,读完才可以写入)
- (feekBackModel *)model{
__block feekBackModel *models;
dispatch_sync(_modelDateQ, ^{
NSLog(@"getter ----------------");
models = [_model mutableCopy];
});
return models;
}
//异步写入(在前面的读取工作完成后,多个同时写)
- (void)setModel:(feekBackModel *)model{
dispatch_barrier_async(_modelDateQ, ^{
NSLog(@"setter ++++++++++++");
_model = [model mutableCopy];
});
}
关键是调用的时候:要修改model属性的值,不能直接用self.model属性,这样直接调用的get方法。要先采用get方法,拷贝一个对象出来,然后修改该对象的属性值,再把该对象直接赋值给拷贝前的对象,这样才可以调用setter。
@synthesize delegates = _delegates;
- (NSMutableArray *)delegates{
__block NSMutableArray *delegates;
dispatch_sync(_flyDataQueue, ^{
delegates = [_delegates mutableCopy];
});
return delegates;
}
- (void)setdelegates:(NSMutableArray *)delegates {
dispatch_barrier_async(_flyDataQueue, ^{
_delegates = [delegates mutableCopy];
});
}
以后你调用的这个数组都是线程安全的
数组的读写安全也可以采用上面的方法.
添加元素和删除元素或读取元素都是加锁的。
同步读取,异步添加,读取的时候数组不能添加元素。
数组添加元素可以多任务执行但这个是时候是上锁了的,不能读取。
参考文章:GCD