问题 NSObject的保留方法是原子的吗?


NSObject的保留方法是原子的吗?

例如,当从两个不同的线程保留相同的对象时,它是否承诺保留计数增加了两倍,或者保留计数是否可能只增加一次?

谢谢。


6339
2018-01-17 13:13


起源



答案:


NSObject 以及对象分配和保留计数函数是线程安全的 - 请参阅 附录A:线程安全摘要 在里面 线程编程指南


编辑:我决定看一下Core Foundation的开源部分。在 CFRuntime.c__CFDoExternRefOperation() 是负责更新保留计数器的函数。它测试进程是否有多个线程,如果有多个线程,它会在更新保留计数之前获取自旋锁,从而使此操作线程安全。

有趣的是,保留计数不是一个对象的属性(或实例变量) struct (阶级)感觉。运行时使用保留计数器保持单独的结构。事实上,如果我理解正确,这个结构是一个哈希表数组,并且每个哈希表都有一个自旋锁。这意味着锁是指已放置在同一哈希表中的多个对象,即,锁既不是全局的(对于所有实例)也不是每个实例。


13
2018-01-17 13:29



那是对的。它使用一种称为“锁定条带化”的策略来减少对全局保留锁的争用。这仍然很慢,所以如果你有一个具有非常大的refcount流失的对象,那么实现自定义引用计数系统是值得的。这并不是特别难(使用OSAtomicIncrement()和朋友),但是你将失去检查这些对象的仪器中的refcount历史记录的能力。 - Catfish_Man


答案:


NSObject 以及对象分配和保留计数函数是线程安全的 - 请参阅 附录A:线程安全摘要 在里面 线程编程指南


编辑:我决定看一下Core Foundation的开源部分。在 CFRuntime.c__CFDoExternRefOperation() 是负责更新保留计数器的函数。它测试进程是否有多个线程,如果有多个线程,它会在更新保留计数之前获取自旋锁,从而使此操作线程安全。

有趣的是,保留计数不是一个对象的属性(或实例变量) struct (阶级)感觉。运行时使用保留计数器保持单独的结构。事实上,如果我理解正确,这个结构是一个哈希表数组,并且每个哈希表都有一个自旋锁。这意味着锁是指已放置在同一哈希表中的多个对象,即,锁既不是全局的(对于所有实例)也不是每个实例。


13
2018-01-17 13:29



那是对的。它使用一种称为“锁定条带化”的策略来减少对全局保留锁的争用。这仍然很慢,所以如果你有一个具有非常大的refcount流失的对象,那么实现自定义引用计数系统是值得的。这并不是特别难(使用OSAtomicIncrement()和朋友),但是你将失去检查这些对象的仪器中的refcount历史记录的能力。 - Catfish_Man