在属性声明中,原子和非原子意味着什么?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
这三者之间的操作差异是什么?
在属性声明中,原子和非原子意味着什么?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
这三者之间的操作差异是什么?
当前回答
在单行中:
原子是线程安全的。非原子是线程不安全的。
其他回答
这个问题的其他优秀答案已经定义了语法和语义。因为执行和性能没有很好地详细描述,我将补充我的答案。
这三者之间的功能差异是什么?
我一直认为原子是一个默认值,这很奇怪。在我们工作的抽象级别上,使用类的原子财产作为实现100%线程安全的工具是一个很难的情况。对于真正正确的多线程程序,几乎肯定需要程序员的干预。同时,性能特征和执行还没有详细描述。多年来,我编写了一些大量的多线程程序,一直在声明我的财产是非原子的,因为原子对于任何目的都是不敏感的。在讨论原子和非原子财产这个问题的细节时,我做了一些分析,遇到了一些奇怪的结果。
处决
好的。我首先要澄清的是,锁定实现是由实现定义和抽象的。Louis在他的示例中使用了@synchronized(self)——我认为这是一个常见的混淆来源。该实现实际上没有使用@synchronized(self);它使用对象级自旋锁。Louis的插图很适合使用我们都熟悉的结构进行高级插图,但重要的是要知道它没有使用@synchronized(self)。
另一个区别是,原子财产将在getter中保留/释放对象的循环。
表演
这里有一个有趣的部分:在无竞争(例如单线程)的情况下,使用原子属性访问的性能在某些情况下会非常快。在不太理想的情况下,使用原子访问的开销可能是非原子访问的20倍以上。而使用7个线程的Contested情况下,三字节结构(2.2 GHz Core i7四核,x86_64)的速度慢了44倍。三字节结构是一个非常慢的属性的示例。
有趣的补充说明:三字节结构的用户定义访问器比合成原子访问器快52倍;或合成非原子存取器速度的84%。
在有争议的情况下,物体也可以超过50倍。
由于实现中的优化和变化的数量,很难在这些环境中测量真实世界的影响。你可能经常听到这样的话:“相信它,除非你分析并发现它是个问题”。由于抽象级别的原因,实际上很难衡量实际影响。从概要文件中提取实际成本可能非常耗时,而且由于抽象,非常不准确。同样,ARC与MRC可以产生巨大的差异。
因此,让我们后退一步,不关注属性访问的实现,我们将包括像objc_msgSend这样的常见问题,并在无争议的情况下(以秒为单位的值)检查对NSString getter的许多调用的一些实际高级结果:
MRC|非原子|手动实现的getter:2MRC|非原子|合成吸气剂:7MRC|原子|合成吸气剂:47ARC |非原子|合成吸气剂:38(注意:ARC在此添加了循环引用计数)ARC |原子|合成吸气剂:47
正如你可能已经猜到的,引用计数活动/循环是原子论和ARC下的一个重要贡献。你也会在有争议的案例中看到更大的差异。
虽然我非常关注性能,但我还是说Semantics First!。同时,性能对于许多项目来说是一个低优先级。然而,了解您所使用的技术的执行细节和成本当然不会有什么坏处。你应该根据自己的需要、目的和能力使用正确的技术。希望这将节省您几个小时的比较,并帮助您在设计程序时做出更明智的决定。
原子性原子(默认)
默认为Atomic:如果不键入任何内容,则属性为原子的如果您尝试从它,您将返回一个有效值。它不做任何保证关于这个值可能是什么,但你会得到好的数据,而不是只是垃圾记忆。如果您有多个线程或多个进程指向一个变量,一个线程可以读取,另一个线程可以写入。如果他们同时命中时间,读取器线程保证获得以下两个值之一:在改变之前或改变之后。什么原子没有给你任何形式的保证可能会得到。原子通常与线程安全相混淆,这是不正确的。你需要保证你的线程安全其他方式。然而,atomic将保证,如果您尝试阅读,你会得到某种价值。
非原子的
另一方面,非原子的,正如你可能猜到的,只是意味着,“不要做原子的事情。”你失去的是保证你总是要得到一些东西。如果你试着在写,你可以取回垃圾数据。但另一方面,你去快一点。因为原子财产必须发挥一些魔力为了保证你会得到一个值,它们有点慢。如果这是一个你经常访问的财产,你可能想放弃降到非原子,以确保你不会导致那样的速度处罚通道
礼貌https://academy.realm.io/posts/tmi-objective-c-property-attributes/
原子性属性属性(原子性和非原子性)没有反映在相应的Swift属性声明中,但是当从Swift访问导入的属性时,Objective-C实现的原子性保证仍然有效。
所以 — 如果你在Objective-C中定义了一个原子属性,当Swift使用它时,它仍然是原子属性。
礼貌https://medium.com/@YogevSitton/atomic-vs-非原子属性-拉什课程-d11c23f4366c
默认值是原子的,这意味着无论何时使用该属性都会降低性能,但它是线程安全的。Objective-C的作用是设置一个锁,因此只要执行setter/getter,只有实际线程才能访问变量。
具有ivar_internal的属性的MRC示例:
[_internal lock]; //lock
id result = [[value retain] autorelease];
[_internal unlock];
return result;
因此,后两项相同:
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName; // defaults to atomic
另一方面,非原子对代码没有任何影响。所以只有当你自己编写安全机制时,它才是线程安全的。
@property(nonatomic, retain) UITextField *userName;
关键字根本不必写为第一个属性属性。
别忘了,这并不意味着整个属性是线程安全的。只有setter/getter的方法调用是。但是如果您使用setter,然后同时使用2个不同线程的getter,那么它也可能会被破坏!
原子意味着一次只能有一个线程访问变量(静态类型)。原子是线程安全的,但它很慢。
非原子意味着多个线程可以同时访问变量(动态类型)。非原子线程不安全,但速度很快。
-原子意味着只有一个线程访问变量(静态类型)。-原子是线程安全的。-但它的性能很慢
如何申报:
由于原子是默认的,
@property (retain) NSString *name;
实现文件中的AND
self.name = @"sourov";
假设与三个财产相关的任务是
@property (retain) NSString *name;
@property (retain) NSString *A;
@property (retain) NSString *B;
self.name = @"sourov";
所有财产并行工作(如异步)。
如果从线程A调用“name”,
And
同时如果你打电话
[self setName:@"Datta"]
从线程B,
现在,如果*name属性是非原子的,那么
它将返回A的值“Datta”它将返回B的值“Datta”
这就是为什么非原子被称为线程不安全的原因,但由于并行执行,它的性能很快
现在如果*name属性是原子的
这将确保A的价值“Sourov”然后它将返回B的值“Datta”
这就是为什么原子被称为线程安全和这就是为什么它被称为读写安全
这种情况操作将连续执行。性能缓慢
-非原子意味着多线程访问变量(动态类型)。
-非原子是线程不安全的。
-但它的性能很快
-非原子不是默认行为,我们需要在属性属性中添加非原子关键字。
对于In Swift确认Swift财产在ObjC意义上是非原子的。一个原因是,您需要考虑每个属性的原子性是否足以满足您的需求。
参考:https://forums.developer.apple.com/thread/25642
有关更多信息,请访问网站http://rdcworld-iphone.blogspot.in/2012/12/variable-property-attributes-or.html