What does the property “Nonatomic” mean?
在这段代码中,"非原子"是什么意思?
1
| @property(nonatomic, retain) UITextField *theUsersName; |
原子和非原子的区别是什么?
谢谢
- 抱歉,忘了在Objective-C(Cocoa)中说明这一点。
- 请阅读此链接-stackoverflow.com/questions/588866/…
- 对于任何一个阅读这篇文章的人来说,对于2014年来说,重要的是要意识到很多这方面的信息已经过时了。总之,没有任何理由使用非原子的,而且出于任何原因使用它本质上是错误的。这是古老的历史。非原子的意思是"线程不安全模式",现在完全不相关了。这里有一些评论stackoverflow.com/q/23977765/294884
- 我不同意"不相关"的说法。如果值很少改变,如Apple Doc中的示例所示,则为姓氏。它会更改一次,然后使用原子提示会浪费所涉及的资源,因为不需要进行检查。
- 以下是答案stackoverflow.com/a/32942413/196164
看看苹果文档。
基本上,如果您说nonatomic,并且使用@synthesize生成访问器,那么如果多个线程试图同时更改/读取属性,则可能会发生错误。您可以得到部分写入的值或过度释放/保留的对象,这很容易导致崩溃。(不过,这可能比原子访问器快得多。)
如果使用默认值(即atomic;以前没有关键字,但现在有关键字),那么@synthesized方法使用对象级锁来确保对单个属性进行多次读/写序列化。正如Apple文档所指出的,这并不意味着整个对象是线程安全的,但是单个属性的读/写是线程安全的。
当然,如果您实现自己的访问器而不是使用@synthesize,我认为这些声明除了表达您是否以threadsafe方式实现该属性的意图之外,什么也不做。
- 我喜欢这个答案——比其他地方的答案更简单、更完整!
- 答案很好……
- 真的很好而且不那么令人困惑(+1),但是你能告诉我为什么非原子的访问速度比原子的访问速度快得多吗?
- @希望非原子访问器可以更快,因为要防止其他线程同时读/写,您需要保持互斥或执行一些其他低级别的技巧,这会占用CPU时间。如果您使用的是一个锁,那么您也可以最终阻塞其他线程,这也需要时间。
- @Jesse感谢你的回应。
- 实现访问器是线程安全的最好方法是什么?
- @罗布,你可能想问一个新问题。
- JesseRusak,阅读你提供链接的苹果文档中的以下段落。查看我的下一条评论:
- 注意:考虑一个XYZPerson对象,其中一个人的名字和姓氏都是使用一个线程的原子访问器更改的。如果另一个线程同时访问这两个名称,原子getter方法将返回完整的字符串(不会崩溃),但不能保证这些值是相对正确的名称。如果在更改之前访问了名字,但在更改之后访问了姓氏,则最终会得到一对不一致、不匹配的名字。
- 它说,在原子的情况下,不能保证这些值是相对的正确名称。如果在更改之前访问了名字,但在更改之后访问了姓氏,则最终会得到一对不一致、不匹配的名字。也就是说,你的答案在原子和非原子之间是颠倒的。如果我理解错误,请纠正我。
- @不好意思,这不正确。您所展示的引用与我所做的完全相同:使属性atomic避免访问单个属性时崩溃,但不能确保对象作为一个整体(即访问单独的属性,如名字和姓氏)将做正确的事情。
- 谢谢杰西·鲁萨克。我现在清醒了。我们能说原子是线程安全的吗?另外,如果我的应用程序是多线程的,应该使用什么访问器?原子的还是非原子的?
- @一般来说,这很难回答;如果你有具体的问题,你可能想开始一个新的问题。
- 好的,杰西·鲁萨克。谢谢你的回答,我开始了解新事物。恭喜!!!!
在阅读了这么多的文章和stackoverflow文章,并制作了用于检查变量属性的演示应用程序之后,我决定将所有属性信息放在一起。
原子//默认
非原子的
强=保留//默认
弱=不安全
保持
分配//默认
不安全的
复制
只读
读写//默认
下面是详细的文章链接,您可以在其中找到上面提到的所有属性,这绝对会对您有所帮助。非常感谢所有在这里给出最佳答案的人!!
Variable property attributes or Modifiers in iOS
原子的
- 原子意味着只有一个线程访问变量(静态类型)。
- 原子是线程安全的。
- 但它的性能很慢。
- 原子是默认行为。
- 非垃圾收集环境中的原子访问器(即使用retain/release/autorelease时)将使用锁来确保另一个线程不会干扰值的正确设置/获取。
- 它实际上不是一个关键字。
例子:
1 2 3
| @property (retain) NSString *name;
@synthesize name; |
非原子的
- 非原子意味着多线程访问变量(动态类型)。
- 非原子是线程不安全的。
- 但它的性能很快。
- 非原子不是默认行为;我们需要在属性属性中添加非原子关键字。
- 当两个不同的进程(线程)同时访问同一个变量时,可能会导致意外的行为。
例子:
1 2 3
| @property (nonatomic, retain) NSString *name;
@synthesize name; |
除了已经提到的线程安全性之外,非原子属性比原子访问器更快。这不是你通常需要担心的事情,但请记住。由于这个原因,核心数据生成的属性部分是非原子的。
在多线程程序中,原子操作不能部分中断,而非原子操作可以。
因此,如果您的关键操作是非原子的,而您不希望被中断,那么应该使用互斥体(或类似的东西)。
如果指定"atomic",则生成的访问函数会有一些额外的代码来防止同步更新。
通常,原子意味着对属性的写入/读取是作为单个操作进行的。原子操作
你可以通过阅读下面的文章来了解这些东西。
用非原子的目的解释线程
非原子-非线程安全
原子-线程安全-这是默认属性属性。
- 你确定不是相反的吗?原子性质是安全的,但非原子性质是不安全的。上次我检查的时候是这样的:p
- 现在编辑。贴错了!抓得好。你是对的。
"原子"意味着对属性的访问是线程安全的。而"非原子"则恰恰相反。当您在Objective-C中声明一个属性时,默认情况下该属性是原子的,这样合成的访问器就可以在多线程环境中提供对属性的可靠访问,也就是说,无论其他线程同时执行什么,从getter或setter返回的值总是被完全检索或设置。但是如果你像下面这样声明财产是非原子的
1
| @property (nonatomic, retain) NSString *myString; |
然后它意味着对象属性的合成访问器直接返回值。非原子属性的效果取决于环境。默认情况下,合成的访问器是原子的。所以非原子比原子快得多。
一种是多线程。一个
- 不具体的回答。
- imho:为了得到任何赞成票,你需要更具体一些,花些时间写下你的答案。