美文网首页
atomic和nonatomic/Objective-C单向数据

atomic和nonatomic/Objective-C单向数据

作者: 帅气的阿斌 | 来源:发表于2018-05-11 18:11 被阅读41次

    Objective-C单向数据流方案(多个页面公用一个数据,最后的页面获取到了最新的数据,其余页面同步更新解决方案)

    基础:atomic和nonatomic的对比

    起因:

    当我们在写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单向数据流的实际应用

    相关文章

      网友评论

          本文标题:atomic和nonatomic/Objective-C单向数据

          本文链接:https://www.haomeiwen.com/subject/rtfqdftx.html