“非原子”属性是什么意思?


144

此代码中的“非原子”是什么意思?

@property(nonatomic, retain) UITextField *theUsersName;

原子和非原子有什么区别?

谢谢


3
抱歉,忘了指定这是在Objective-c(可可)中


对于任何阅读此书的人来说,对于2014年而言,重要的是要意识到很多此类信息已经过时了。一言以蔽之,没有理由使用非原子,并且出于任何原因而使用它本质上是错误的。这是古老的历史。非原子的意思是“线程不安全模式”,并且(一句话)现在完全不相关。一些评论这里stackoverflow.com/q/23977765/294884
Fattie 2014年

我不同意“不相关的”声明。如果值更改很少,并且以Apple doc中的示例为姓。一旦使用原子提示,它就会更改,因为不需要检查,因此使用原子提示会浪费资源。
Nick Turner

Answers:


268

看一下Apple Docs

基本上,如果您说nonatomic,并且您使用生成了访问器@synthesize,那么如果多个线程尝试一次更改/读取该属性,则可能发生错误。您可以获得部分写入的值或过度释放/保留的对象,这很容易导致崩溃。(不过,这可能比原子访问器快很多。)

如果您使用默认值(即atomic;以前没有关键字,但是现在有),则@synthesize d方法使用对象级锁来确保对单个属性的多个读/写被序列化。正如Apple文档所指出的,这并不意味着整个对象都是线程安全的,但是单个属性的读写是。

当然,如果您实现自己的访问器而不是使用@synthesize,我认为这些声明除了表示您是否打算以线程安全的方式实现该属性外,什么都不做。


7
我喜欢这个答案-比其他地方的答案更混乱,更简单,更完整!
PapillonUK

确实很棒,很少混淆(+1),但是您能否告诉我为什么非原子可能比原子访问器快得多?
希望

2
@Wish非原子访问器可以更快,因为要防止其他线程同时读取/写入,您需要持有一个互斥锁或执行一些其他的低级技巧,这会花费CPU时间。如果您使用的是锁,那么最终也可能会阻塞其他线程,这也需要花费时间。
杰西·鲁萨克

1
@Rob您可能想问一个新的问题。
杰西·鲁萨克

1
@Pratik对不起,那是不正确的。您显示的引语与我所做的事情完全相同:创建属性atomic可以避免在访问单个属性时发生崩溃,但不能确保整个对象(即访问诸如名字和姓氏之类的单独属性)将要执行的操作正确的事情。
杰西·鲁萨克

46

阅读了如此多的Articles和StackOverflow帖子,并制作了演示应用程序来检查Variable属性属性之后,我决定将所有属性信息放在一起

  1. 原子//默认
  2. 非原子
  3. strong =保留//默认
  4. 弱=不安全未保留
  5. 保留
  6. 分配//默认
  7. unsafe_unretained
  8. 复制
  9. 只读
  10. readwrite //默认

因此,下面是详细的文章链接,您可以在其中找到上述所有属性,这些绝对会对您有所帮助。非常感谢在这里给出最佳答案的所有人!!

iOS中的可变属性属性或修饰符

  1. 原子
    • 原子意味着只有一个线程可以访问变量(静态类型)。
    • 原子是线程安全的。
    • 但是它的性能很慢。
    • 原子是默认行为。
    • 在非垃圾回收环境中(例如,在使用保留/释放/自动释放时),原子访问器将使用锁来确保另一个线程不会干扰该值的正确设置/获取。
    • 它实际上不是关键字。

范例:

@property (retain) NSString *name;

@synthesize name;
  1. 非原子
    • 非原子意味着多线程访问变量(动态类型)。
    • 非原子是线程不安全的。
    • 但是它的性能很快。
    • 非原子不是默认行为;我们需要在属性属性中添加非原子关键字。
    • 当两个不同的进程(线程)同时访问同一变量时,可能会导致意外行为。

例:

@property (nonatomic, retain) NSString *name;

@synthesize name;

12

除了已经说过的关于线程安全性之外,非原子属性比原子访问器还快。您通常不必担心这件事,但请记住这一点。因此,核心数据生成的属性部分是非原子的。


9

在多线程程序中,原子操作不能部分中断,而非原子操作可以。

因此,如果您有不希望中断的非原子操作,则应使用互斥锁(或类似方法)。


8

如果指定“ atomic”,则生成的访问函数将具有一些额外的代码来防止同时更新。




0

“原子”的手段,获得的属性是线程安全的。而‘非原子’是它的对面。当你声明的Objective-C的一个属性的属性都默认原子,使合成的访问器提供强大的访问属性在多线程环境中,也就是说,无论其他线程正在同时执行,从getter或setter设置返回的值始终会被完全检索或设置。

@property (nonatomic, retain)  NSString *myString;

那么这意味着对象属性的综合访问器仅直接返回该值。非原子属性的效果取决于环境。默认情况下,综合访问器是原子的。因此,非原子比原子快得多。


-2

一种是用于多线程。一个不是


恕我直言:为了获得任何投票,您需要更加具体,花一些时间来编写答案。
约翰·卡尔森
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.