熟悉Cocoa iPhone / Mac开发,我知道 atomic 和非原子属性之间的区别,以及与非原子的性能差异,但IBOutlet的每个定义我见过的属性指定nonatomic,超过默认原子。我无法找到这是一个要求还是仅仅是有利的解释?任何人都可以进一步解释吗?
谢谢!
-Ben
答案 0 :(得分:1)
这不是必需的。事实上,你可以完全没有声明属性。
@interface MyClass
{
IBOutlet UIView *someView;
}
@end
然而,人们使用属性是因为更容易进行内存管理(retain关键字将确保插座保留在内存中直到调用release;它会在卸载视图时释放,否则我相信)。非原子只是跟随,因为它默认设置为原子 - 如果没有理由使用原子,你应该使用非原子。
答案 1 :(得分:0)
大多数UIKit类/函数都不是线程安全的(UIGraphics最近有点线程安全,显然,但我怀疑UIView仍然没有),因此使用原子属性没有多大意义。原子“保留”属性仅防止这种竞争条件(假设指针分配已经是原子的):
NSLog([obj.property description]);
obj.property = nil;
导致属性被释放。如果在获取属性并使用NSLog打印它之间的某个时刻发生这种情况,它可能会崩溃(例如,“描述”字符串可能由对象拥有,并且可能在它被释放时消失。)通常,对于大多数类型的线程同步,您需要比原子getter / setter 更多; setter获得一个@synchronized块,getter(假设一个“retain”属性)获得一个@synchronized块,一个retain和一个autorelease。 @synchronized块由_lock和_unlock方法调用(IIRC)组成。这是四个方法调用和一个异常处理程序!
为“线程安全”或“健壮性”创建属性原理有点像使变量变为“稳健性”而不是使用内存障碍 - 它可能看起来更安全,但它通常只会增加额外的开销而没有任何好处并且可能隐藏潜在的并发问题。
编辑:是的,自动释放必须在getter中,而不是setter。否则,该对象由B的自动释放池拥有,该池可能随时被释放,但是由于该对象在被释放之前会长时间停留,因此会隐藏该bug。