在属性声明中,原子和非原子意味着什么?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

这三者之间的操作差异是什么?


当前回答

了解差异的最佳方法是使用以下示例。

假设有一个名为“name”的原子字符串属性,如果您从线程A调用[self-setName:@“A”],从线程B调用[selfsetName:@“B”],并从线程C调用[self name],那么不同线程上的所有操作都将串行执行,这意味着如果一个线程正在执行setter或getter,那么其他线程将等待。

这使得属性“name”读/写安全,但如果另一个线程D同时调用[namerelease],那么这个操作可能会产生崩溃,因为这里没有setter/getter调用。这意味着一个对象是读/写安全的(ATOMIC),但不是线程安全的,因为另一个线程可以同时向该对象发送任何类型的消息。开发人员应确保此类对象的线程安全。

如果属性“name”是非原子的,那么上面示例中的所有线程(A、B、C和D)将同时执行,产生任何不可预测的结果。在原子的情况下,A、B或C中的任何一个将首先执行,但D仍然可以并行执行。

其他回答

原子:

原子保证以原子的方式访问财产。例如,它总是返回一个完全初始化的对象,一个线程上的属性的任何获取/设置都必须在另一个线程访问它之前完成。

如果你想象一下下面的函数同时出现在两个线程上,你就会明白为什么结果不好看。

-(void) setName:(NSString*)string
{
  if (name)
  {
    [name release]; 
    // what happens if the second thread jumps in now !?
    // name may be deleted, but our 'name' variable is still set!
    name = nil;
  }

  ...
}

赞成的意见:每次返回完全初始化的对象是多线程情况下的最佳选择。

欺骗:性能受到影响,执行速度稍慢

非原子:

与Atomic不同,它不能确保每次都返回完全初始化的对象。

赞成的意见:执行速度极快。

欺骗:在多线程的情况下,可能会产生垃圾值。

Atomic是线程安全的,它很慢,而且它很好地保证(不保证)无论有多少线程试图访问同一区域,都只提供锁定值。使用atomic时,在该函数中编写的一段代码成为关键部分的一部分,一次只能执行一个线程。

它只保证螺纹安全;它不能保证这一点。我的意思是,你们为你们的汽车雇佣了一名专家司机,但这并不能保证汽车不会发生事故。然而,可能性仍然微乎其微。

原子——它无法分解,所以结果是意料之中的。使用非原子-当另一个线程访问内存区域时,它可以修改它,因此结果是意外的。

代码对话:

原子使属性线程的getter和setter安全。例如,如果你写了:

self.myProperty = value;

是线程安全的。

[myArray addObject:@"Abc"] 

不是线程安全的。

首先最简单的回答是:第二个例子之间没有区别。默认情况下,属性访问器是原子的。

非垃圾收集环境中的原子访问器(即,当使用retain/release/autorelease时)将使用锁来确保另一个线程不会干扰值的正确设置/获取。

有关更多信息以及创建多线程应用程序时的其他注意事项,请参阅苹果Objective-C 2.0文档的“性能和线程”部分。

如果您使用的是atomic,这意味着线程将是安全且只读的。如果您使用的是非原子的,这意味着多个线程访问变量,并且线程不安全,但它执行速度很快,执行了读写操作;这是一种动态类型。

原子属性确保保留完全初始化的值,而不管有多少线程在其上执行getter和setter。

非原子属性指定合成访问器只需直接设置或返回一个值,而不保证从不同线程同时访问同一个值会发生什么。