• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

Objective-C的atomic和nonatomic

武飞扬头像
KFAaron
帮助1

在谈atomic之前,有必要看下究竟什么是原子和原子操作。原子,顾名思义,就是最小的不可分割的粒子,在这里先不考虑夸克粒子,可以把原子这个词象征性化。原子操作,就是一个或一系列不可分割和阻断的操作。

atomic做了啥

在Objective-C中,property默认是atomic的。根据官方文档,设置原子性,通过setter和getter方法对数据进行读写时可以保证数据的准确性。因为它内部的实现是私有的,我们可以参考objc4的源码。

setter方法
static inline void reallySetProperty(id self, SEL _cmd, id newValue, ptrdiff_t offset, bool atomic, bool copy, bool mutableCopy)
{
    ...

    if (!atomic) {
        oldValue = *slot;
        *slot = newValue;
    } else {
        spinlock_t& slotlock = PropertyLocks[slot];
        slotlock.lock();
        oldValue = *slot;
        *slot = newValue;        
        slotlock.unlock();
    }

    objc_release(oldValue);
}
getter方法
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
    ...

    // Retain release world
    id *slot = (id*) ((char*)self   offset);
    if (!atomic) return *slot;
        
    // Atomic retain release world
    spinlock_t& slotlock = PropertyLocks[slot];
    slotlock.lock();
    id value = objc_retain(*slot);
    slotlock.unlock();
    
    // for performance, we (safely) issue the autorelease OUTSIDE of the spinlock.
    return objc_autoreleaseReturnValue(value);
}

通过源码可以看到,设置atomic之后,setter和getter方法在进行读写操作时会先进行加锁的动作,等操作完成之后再解锁。这样就保证的读写数据的完整性。

atomic能否保证线程安全

官方文档里有明确提示,原子性不等同于对象的线程安全。

文档中举了个简单的例子。在一个线程中,一个人的姓和名都在变。同一时间从另一个线程想获取这个人的姓名。 学新通网 通过图可以看出,如果姓还未改时访问姓,名已改时访问名,这时候就可能会发生一个错配的情况。实际上这个人的名字只是从张三改成李四,而另一个线程可能获取到张四这个名。

这只是一个最简单的例子。其实还可以考虑比如property是一个可变数组等等。由此可见,atomic只是通过在setter和getter方法里加锁保证数据读写的完整性,并不能保证对象的线程安全。

为什么要用nonatomic

在iOS开发中,更多关注的是对象的线程安全,而property本身数据的原子性影响反而不是那么大。因为设置atomic,在set和get时,还有加锁和解锁的过程,增加性能的开销。设置nonatomic则可以免了这些动作。因此,如果需要在不同线程保证数据的准确性和一致性,则使用atomic,这里只对通过setter和getter方法对这个数据本身进行读写时有效。否则则可以设置为nonatomic。

You can use the nonatomic property attribute to specify that synthesized accessors simply set or return a value directly, with no guarantees about what happens if that same value is accessed simultaneously from different threads. For this reason, it’s faster to access a nonatomic property than an atomic one

参考

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhbfbaab
系列文章
更多 icon
同类精品
更多 icon
继续加载