Objective c Obj-c2.0中合成原子@属性的锁定细节

Objective c Obj-c2.0中合成原子@属性的锁定细节,objective-c,cocoa,multithreading,Objective C,Cocoa,Multithreading,Obj-c2.0中的属性文档称原子属性在内部使用锁,但没有记录锁的细节。有人知道这是一个每属性锁,一个与@synchronized(self)使用的隐式锁分开的每对象锁,还是与@synchronized(self)等效的锁吗?原子@properties使用的锁是一个实现细节——适用于适当平台上的适当类型,没有锁的原子操作是可能的,如果苹果没有利用它们,我会感到惊讶。在任何情况下都没有对锁的公共访问权限,因此不能在同一个锁上@synchronize。几位苹果工程师指出,原子属性不能保证线程安全;原

Obj-c2.0中的属性文档称原子属性在内部使用锁,但没有记录锁的细节。有人知道这是一个每属性锁,一个与@synchronized(self)使用的隐式锁分开的每对象锁,还是与@synchronized(self)等效的锁吗?

原子@properties使用的锁是一个实现细节——适用于适当平台上的适当类型,没有锁的原子操作是可能的,如果苹果没有利用它们,我会感到惊讶。在任何情况下都没有对锁的公共访问权限,因此不能在同一个锁上@synchronize。几位苹果工程师指出,原子属性不能保证线程安全;原子属性仅保证该值的get/set是原子的。为了正确的线程安全,您必须使用更高级别的锁定或同步,并且您几乎肯定不希望使用与综合getter/setter可能使用的相同的锁定。

查看生成的代码(iOS SDK GCC 4.0/4.2用于ARM)

  • 直接访问32位
    assign
    属性(包括
    struct{int32_t v;}
  • 使用objc_copyStruct()访问大于32位的结构
  • double
    int64\u t
    通过objc\u copyruct访问,GCC 4.0除外,在GCC 4.0中,它们直接通过stmia/ldmia访问(我不确定这是否保证在中断情况下是原子的)
  • 保留/复制访问器调用objc_getProperty和objc_setProperty

给出了在中如何实现它们的一些细节;显然,运行时之间的精确实现可能有所不同(例如,在某些平台上,您可以使用原子交换/CAS在ivar本身上旋转,而不是使用另一个锁)。

Ok。我问这个问题是因为我想知道当同时处理多个属性时,使用原子属性和@synchronized()是否会有额外的开销。听起来,对于不能使用原子原语完成的操作,会有额外的开销,因为它有效地使用了2个锁。在这种情况下,当您已经使用@synchronized或其他受保护的块来实现更高级别的锁定语义时,对您的属性使用非原子可能是有意义的。我不想让代码的所有客户端都必须使用@synchronized块来访问属性,我也不想实现自己的getter/setter,只是为了使用@synchronized而不是合成的同步操作。如果您使用更高级别的同步命令访问包含这些属性的资源,但允许其他客户端直接访问这些属性,可能很难保证依赖于更高级别同步的多线程代码的正确行为。当然是YMMV,但要小心。我甚至没有使用@synchronized,而是使用了一些显式的NSLock对象(用于锁定单个私有ivar),我依赖于属性访问的顺序。我相信,按照我对属性赋值的排序方式,即使从另一个线程,客户端也始终拥有对象的可用视图(例如,如果图像未标记为已完成,则可以对其进行设置,但如果图像标记为已完成,则始终会对其进行设置)。