24

如果你从 Interface Builder 拖一个新的 outlet 到一个接口(头)文件,Xcode 4.6 会自动为你创建一个属性...

在 iOS (Cocoa Touch) 上,它看起来像这样:

@property (weak, nonatomic) SomeClass *someProperty; //nonatomic accessors

而在 OS X (Cocoa) 上它看起来像这样:

@property (weak) SomeClass *someProperty; //atomic accessors (implicitly)

为什么?

编辑:我不是在问 atomic 做什么或不做什么,我很清楚同步指令和保证 setter 和 getter 原子性的底层互斥锁(或锁或其他)。我知道在 iOS 上,访问器是非原子的,因为 UIKit 不是线程安全的,因此使它们成为原子没有任何好处,这只是浪费处理器时间和电池寿命。我在这里谈论的是默认情况,知道自己在做什么的程序员会知道何时需要使访问器原子化。

所以我问为什么它们在 OS X 上默认是原子的。我的印象是 Appkit 也不是线程安全的。并且拥有原子访问器并不能保证线程安全,我什至可以说它是相反的,因为它可以给新手程序员带来线程安全的错觉,并通过延迟崩溃使并发应用程序中的错误跟踪更加困难到以后的时间,这样做使它们更难追踪。并且仅仅因为台式机相对强大并不意味着资源应该被浪费(注意我这里不是在谈论过早的优化),而且既然苹果工程师是合理的程序员,那么他们必须有一个很好的理由。决定让属性默认合成原子访问器。

4

4 回答 4

7

在这种情况下,atomic说明符告诉编译器应该综合设置器和访问器,以便安全地从多个线程调用。这通过要求方法在可以写入或读取属性值之前取出锁而增加了少量开销。

由于 UIKit 和 Cocoa 的用户界面元素只打算从主线程访问,因此不需要额外的锁。使属性原子化的开销非常小,但在 iOS 更受限制的环境中,每一盎司的速度都是有价值的。因此,为什么 iOS 默认使用nonatomicIB Outlets 属性。

针对您的扩展问题进行了编辑:我的感觉是使用原子属性的成本值得在 Mac 上花费。有一种说法是使用原子属性掩盖了一系列错误,因此是一件坏事。我认为,从用户的角度来看,Apple 应该设置默认值,这样即使是编码错误的应用程序也会更少崩溃。它让高级程序员有责任知道何时可以安全地使用非原子属性来换取性能优势。

当时没有听到团队中某人的消息,我们只能推测他们的思维过程,但我相信这是一个经过深思熟虑的决定。

于 2013-03-12T13:40:15.867 回答
4

简单得要命:原子通过其隐式互斥机制导致开销(在 OSX 上可以忽略不计)。

iOS(作为 ARM 芯片上的嵌入式系统)无法承受这种开销,因此 IBOutlets 默认为非原子。

一言以蔽之:性能

至于为什么它们在 OSX 上默认为原子,属性上的线程安全是在像 OSX 这样的大规模多线程、多应用程序环境中拥有的一件好事(特别是与 iOS 相比,应用程序更有可能在OSX 比 iOS 上)。

如前所述,OSX 上的开销真的可以忽略不计,因此他们默认它是这样的。

于 2013-03-21T13:48:06.073 回答
3

在这个问题中,关于原子属性与非原子属性的争论相当冗长:原子属性和非原子属性之间有什么区别?我敢打赌,这与通常在 OSX 应用程序与 iOS 应用程序中发现的界面的相对复杂性有关。让 OSX 应用程序一直在多个线程上运行是相当普遍的。因此,这些接口有助于在多线程环境中更普遍地运行。在 iOS 中,虽然随着系统的成熟,应用程序肯定会变得越来越复杂,但它们仍然运行在一个更基本的操作系统上,该操作系统目前更适合非线程环境。

还有一些关于非原子属性的讨论通常比原子属性具有更少的开销,并且通常在 iOS 设备中具有更小的 CPU 和更少的内存,除非需要额外的开销,否则将属性默认为非原子是有意义的。

于 2013-03-12T13:37:15.153 回答
1

OSX 可以控制多线程,而且大部分应用程序都使用多线程。因此默认设置为原子。

而在 iOS 的情况下,你很少会使用多个线程,所以非原子为你服务。

于 2013-03-12T13:19:37.753 回答