美文网首页
iOS atomic与nonatomic的区别以及各自功能

iOS atomic与nonatomic的区别以及各自功能

作者: 尼古拉斯佩思 | 来源:发表于2019-08-06 14:24 被阅读0次

    一、atomic与nonatomic的区别!

    首先,先介绍一下atomicnonatomic
    1.atomic使用同步锁,原子性:

    在该属性在调用gettersetter方法时,会加上自旋锁(osspinlock)
    即在属性在调用gettersetter方法时,保证同一时刻只能有一个线程调用属性的读/写方

    2.nonatomic:不使用同步锁,非原子性:

    在该属性在调用getter和setter方法时,不会加上自旋锁,也就是线程并不安全

    然后,再介绍一下atomicnonatomic的申明方式
    @property(nonatomic,strong) NSString *test;
    
    @property (atomic,strong) NSString *test;
    
    @property (strong) NSString *test;
    

    代码中可以看到这样的书写方式,那么这三个代码有什么不同呢?

    其实:

    @property (atomic,strong) NSString *test;
    
    @property (strong) NSString *test;
    

    这两个代码完全是一样的结果,省略不写即默认为atomic,而不是nonatomic

    中间,我为什么强调atomic属性申明时在调用gettersetter方法时会加上自旋锁(osspinlock)并且是只能有一个线程调用属性的读/写方法,没有说线程是安全的

    对于atomic的属性,系统生成的 getter/setter会保证 get、set 操作的完整性,不受其他线程影响。
    比如,线程 A 的 getter方法运行到一半,线程 B 调用了 setter:那么线程 A 的 getter还是能得到一个完好无损的对象。

    如果有一个 atomic的属性 "name",如果线程 A 调[self setName:@"A"],线程 B 调[self setName:@"B"],线程 C 调[self name],那么所有这些不同线程上的操作都将依次顺序执行——也就是说,如果一个线程正在执行 getter/setter,其他线程就得等待。因此,属性 name是读/写安全的。

    但是,如果有另一个线程 D 同时在调[name release],那可能就会crash,因为 release不受 getter/setter操作的限制。也就是说,这个属性只能说是读/写安全的,但并不是线程安全的,因为别的线程还能进行读写之外的其他操作。线程安全需要开发者自己来保证

    最后为什么说nonatomic线程并不安全

    如果 name属性是 nonatomic 的,那么上面例子里的所有线程 A、B、C、D 都可以同时执行,可能导致无法预料的结果。如果是atomic 的,那么 A、B、C 会串行,而 D 还是并行的。

    其实苹果官方文档也有解释
    还有自旋锁osspinlock因为并不安全已经被苹果淘汰,替换成为自旋锁os_unfair_lock,详情可以参考YY大神ibireme 不再安全的 OSSpinLock

    以后的文章我会表述iOS锁的概念和的常见的几种锁

    相关文章

      网友评论

          本文标题:iOS atomic与nonatomic的区别以及各自功能

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