在属性声明中,原子和非原子意味着什么?
@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;
这三者之间的操作差异是什么?
当前回答
原子意味着一次只能有一个线程访问变量(静态类型)。原子是线程安全的,但它很慢。
非原子意味着多个线程可以同时访问变量(动态类型)。非原子线程不安全,但速度很快。
其他回答
最后两个是相同的;“atomic”是默认行为(请注意,它实际上不是一个关键字;它仅在不存在非atomic的情况下被指定——在最近版本的llvm/claung中,atomic被添加为关键字)。
假设您正在@合成方法实现,原子与非原子将更改生成的代码。如果您正在编写自己的setter/getter,原子/非原子/保留/分配/复制只是建议。(注意:@synthey现在是LLVM最新版本中的默认行为。也不需要声明实例变量;它们也会自动合成,并且在名称前加一个_,以防止意外的直接访问)。
使用“atomic”,合成的setter/getter将确保始终从getter返回或由setter设置整个值,而不管setter在任何其他线程上的活动如何。也就是说,如果线程A位于getter的中间,而线程B调用setter,则实际可行的值(很可能是自动释放的对象)将返回给A中的调用方。
在非原子中,没有这样的保证。因此,非原子比“原子”快得多。
“原子”不做的是保证线程安全。如果线程A同时调用getter,而线程B和C使用不同的值调用setter,那么线程A可能会得到返回的三个值中的任何一个值——在调用setter之前的值,或者在B和C中传递给setter的值。同样,对象可能会以B或C的值结束,这是无法分辨的。
确保数据完整性——多线程编程的主要挑战之一——是通过其他方式实现的。
添加到此:
当使用多个依赖财产时,单个属性的原子性也不能保证线程安全。
考虑:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
在这种情况下,线程A可以通过调用setFirstName:然后调用setLastName:来重命名对象。同时,线程B可以在线程A的两次调用之间调用fullName,并将接收新的名字和旧的姓氏。
要解决这个问题,您需要一个事务模型。也就是说,某些其他类型的同步和/或排除允许在更新依赖财产时排除对fullName的访问。
我在这里找到了原子和非原子财产的一个很好的解释。以下是一些相关文本:
“原子”意味着它不能分解。在OS/编程术语中,原子函数调用是一个不能中断的调用——必须执行整个函数,并且在完成之前,不能通过操作系统通常的上下文切换将其从CPU中移出。万一你不知道:由于CPU一次只能做一件事,操作系统会在很小的时间段内对所有正在运行的进程轮流访问CPU,从而产生多任务的错觉。CPU调度器可以(并且确实)在进程执行的任何时间点中断进程,即使是在函数调用中间。因此,对于像更新共享计数器变量这样的操作,如果两个进程可以同时尝试更新变量,则必须“原子”地执行这些操作,即,每个更新操作必须完整完成,然后才能将任何其他进程交换到CPU上。所以我猜测,在这种情况下,原子意味着属性读取器方法不能被中断,实际上意味着该方法读取的变量不能中途更改其值,因为其他线程/调用/函数被交换到CPU上。
因为原子变量不能被中断,所以它们在任何时候包含的值(线程锁)都保证不会被破坏,尽管确保这个线程锁会使对它们的访问变慢。另一方面,非原子变量不能保证这一点,但确实提供了快速访问的奢侈。总之,当您知道变量不会被多个线程同时访问时,可以使用非原子的,这样可以加快速度。
Atomic是线程安全的,它很慢,而且它很好地保证(不保证)无论有多少线程试图访问同一区域,都只提供锁定值。使用atomic时,在该函数中编写的一段代码成为关键部分的一部分,一次只能执行一个线程。
它只保证螺纹安全;它不能保证这一点。我的意思是,你们为你们的汽车雇佣了一名专家司机,但这并不能保证汽车不会发生事故。然而,可能性仍然微乎其微。
原子——它无法分解,所以结果是意料之中的。使用非原子-当另一个线程访问内存区域时,它可以修改它,因此结果是意外的。
代码对话:
原子使属性线程的getter和setter安全。例如,如果你写了:
self.myProperty = value;
是线程安全的。
[myArray addObject:@"Abc"]
不是线程安全的。
-原子意味着只有一个线程访问变量(静态类型)。-原子是线程安全的。-但它的性能很慢
如何申报:
由于原子是默认的,
@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
如果您使用的是atomic,这意味着线程将是安全且只读的。如果您使用的是非原子的,这意味着多个线程访问变量,并且线程不安全,但它执行速度很快,执行了读写操作;这是一种动态类型。