OBJC_ASSOCIATION_ASSIGN意味着是原子的还是非原子的?

5
OBJC_ASSOCIATION_ASSIGN,即objc_setAssociatedObject的第四个参数,是原子性的还是非原子性的?
这个枚举被定义为:
enum {
    OBJC_ASSOCIATION_ASSIGN = 0,
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1,
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3,
    OBJC_ASSOCIATION_RETAIN = 01401,
    OBJC_ASSOCIATION_COPY = 01403
};

@property(assign, atomic) id idAssignAtomic;是什么意思?

@property(assign, nonatomic) id idAssignNonatomic;是什么意思?


3
按编号方式推断,应该不是原子的。 - Richard J. Ross III
关于原子和非原子赋值,CLANG在使用对象属性时生成相同的代码,只有在读取时前者保证了整个值,而后者则让你自己处理。 - CodaFi
@CodaFi,你的意思是OBJC_ASSOCIATION_ASSIGN既适用于@property(assign, atomic)也适用于@property(assign, nonatomic)吗? 我需要了解这个问题以便完成https://github.com/kissrobber/DProperty。 - kissrobber
2
相关对象不保证原子性(至少在公开的情况下不保证)。假设为非原子操作。 - CodaFi
再考虑一下这个问题,对于类型为ASSIGN的值,关于原子性的担忧实际上是无关紧要的(至少从公共角度来看)。如果将atomic / nonatomic与它们在Objective-C属性上使用时的等效物进行比较,则具有与指针相同大小且在iOS / OSX支持的所有平台上都是“assign”的属性的“原子性”实际上是无关紧要的,因为字大小的存储总是会在处理器级别上原子化。这里原子性的重要区别在于保留/释放的行为,而不是值的存储。 - Richard J. Ross III
显示剩余2条评论
1个回答

1

目前(截至iOS 8和OS X 10.10),所有关联都是原子性的。如果我们查看objc-references.mm的源代码,就可以看到这一点:

// class AssociationsManager manages a lock / hash table singleton pair.
// Allocating an instance acquires the lock, and calling its assocations() method
// lazily allocates it.

class AssociationsManager {
    static spinlock_t _lock;
    static AssociationsHashMap *_map;               // associative references:  object pointer -> PtrPtrHashMap.
public:
    AssociationsManager()   { spinlock_lock(&_lock); }
    ~AssociationsManager()  { spinlock_unlock(&_lock); }

    AssociationsHashMap &associations() {
        if (_map == NULL)
            _map = new AssociationsHashMap();
        return *_map;
    }
};

具体而言,请注意_lock_map都是静态的,并且被定义为这样:

spinlock_t AssociationsManager::_lock = SPINLOCK_INITIALIZER;
AssociationsHashMap *AssociationsManager::_map = NULL;

当获取关联并释放它时,我们会看到以下内容:

AssociationsManager manager;
AssociationsHashMap &associations(manager.associations());

这清楚地表明每个关联都是原子的,并且独立于在过程中存储或检索的所有其他关联。

请记住,尽管如此,在运行时中的任何内容都可能在未来的发布中发生变化,您不应该依赖此行为进行除学术目的以外的任何操作。


嗨,那么根据你上面的评论,我们是否仍然应该假设它是非原子的呢?还是根据你的答案,将其视为原子的呢?由于性能原因,我也会认为它是非原子的。我只是在猜测而已。谢谢。 - Unheilig
1
@Unheilig总是遵循公共文档,如果可以的话。所以在这种情况下,即使作为实现细节它是原子性的,也应该假设它是非原子性的。 - Richard J. Ross III
虽然我同意您的观点,即我们应该始终遵循公共文档;但是,如果在实现细节上它是原子性的,而在文档中声称它是非原子性的,他们如何使其正常工作呢?尽管我知道“它只是起作用”,不需要我知道它是如何工作的,但我对这些琐碎的细节如何在幕后运行感到好奇。谢谢。 - Unheilig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接