Objective-C单向数据流方案(多个页面公用一个数据,最后的页面获取到了最新的数据,其余页面同步更新解决方案)
起因:
当我们在写Objective-C代码时,会习惯性地把model对象的属性定义为nonatomic。如果该属性是被多线程访问的,那么这样做是有可能crash的。如下:两个线程因为while语句会重复执行对message属性进行赋值和读取操作,执行几遍后会抛出EXC_BAD_ACCESS异常。
......
@property (nonatomic, copy) NSArray *messages;
......
dispatch_async(dispatch_get_global_queue(0,0), ^{
while (1) {
self.messages = [[NSArray alloc] initWithObjects:@1, @2, @3, nil];
}
});
dispatch_async(dispatch_get_global_queue(0,0), ^{
while (1) {
NSLog(@"%@", self.messages);
}
});
atomic真的能保证对象的线程安全?
我们把上面的数据noatomic改成atomic后,发现不会奔溃了!但是实际上,数据的线程安全还是得不到保障的,也就是说多个线程获取或者修改数据,还是会出现数据不统一!!这里的线程安全我觉得只是保证了不会崩溃而已,如下:
引用:
atomic真的能保证对象的线程安全?我们看《realm》对atomic和nonatomic的解释
Atomic is really commonly confused with being thread-safe, and that is not correct. You need to guarantee your thread safety other ways.这句话明确说明Atomic不能保证对象多线程的安全。所以Atomic 不能保证对象多线程的安全。它只是能保证你访问的时候给你返回一个完好无损的Value而已。举个例子:
如果线程 A 调了 getter,与此同时线程 B 、线程 C 都调了 setter——那最后线程 A get 到的值,有3种可能:可能是 B、C set 之前原始的值,也可能是 B set 的值,也可能是 C set 的值。同时,最终这个属性的值,可能是 B set 的值,也有可能是 C set 的值。所以atomic可并不能保证对象的线程安全。
解决方案:在使用noatomic的情况下,使用单向数据流来解决这个问题,也就是数据驱动视图!视图通过订阅这个方法来监听数据的变化,如果数据发生变化,监听方法就会被触发。避免了多个视图可能会产生多个线程来处理数据导致多线程问题!
第三方库:Reflow github地址:Reflow下载地址
应用样例请前往:Objective-C单向数据流的实际应用