原子和非原子属性之间有什么区别?
属性声明中的atomic
和nonatomic
是什么意思?
@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;
这三者之间的运作差异是什么?
最后两个是相同的; “atomic”是默认行为(请注意,它实际上并不是一个关键字;它仅由缺少nonatomic
atomic
来指定 - atomic
在最新版本的llvm / clang中被添加为关键字)。
假设您在@方法实现方法实现,原子与非原子更改生成的代码。 如果你正在编写你自己的setter / getters,atomic / nonatomic / retain / assign / copy只是顾问。 (注意:@synthesize现在是LLVM最新版本中的默认行为,也不需要声明实例变量;它们也会自动合成,并且会在名称前加上_
,以防止意外的直接访问)。
对于“原子”,合成的setter / getter将确保始终从getter返回整个值或由setter设置,而不管任何其他线程上的setter活动。 也就是说,如果线程A位于getter的中间,而线程B调用setter,则实际可用的值 - 最有可能的自动释放对象 - 将在A中返回给调用者。
在nonatomic
,没有这样的保证。 因此, nonatomic
比“原子”快得多。
什么“原子” 不就是做出关于线程安全的任何保证。 如果线程A在线程B和C同时调用getter时使用不同的值调用setter,则线程A可能会返回三个返回值中的任何一个值 - 在调用任何setter之前的值或者传入setters的任一值在B和C中。同样,对象可能以B或C的值结束,无法说明。
确保数据完整性 - 多线程编程的主要挑战之一 - 是通过其他方式实现的。
除此之外:
单个属性的atomicity
性也不能保证多个相关属性在玩时的线程安全性。
考虑:
@property(atomic, copy) NSString *firstName;
@property(atomic, copy) NSString *lastName;
@property(readonly, atomic, copy) NSString *fullName;
在这种情况下,线程A可以通过调用setFirstName:
来重命名对象,然后调用setLastName:
同时,线程B可能会在线程A的两个调用之间调用fullName
,并且会接收到与旧姓氏结合的新名字。
为了解决这个问题,你需要一个事务模型。 即一些其他类型的同步和/或排除,允许在更新从属属性时排除对fullName
访问。
这在Apple的文档中有解释,但下面是实际发生的一些示例。 请注意,没有“原子”关键字,如果不指定“非原子”,那么属性是原子的,但明确指定“原子”会导致错误。
//@property(nonatomic, retain) UITextField *userName;
//Generates roughly
- (UITextField *) userName {
return userName;
}
- (void) setUserName:(UITextField *)userName_ {
[userName_ retain];
[userName release];
userName = userName_;
}
现在,原子变体有点复杂:
//@property(retain) UITextField *userName;
//Generates roughly
- (UITextField *) userName {
UITextField *retval = nil;
@synchronized(self) {
retval = [[userName retain] autorelease];
}
return retval;
}
- (void) setUserName:(UITextField *)userName_ {
@synchronized(self) {
[userName_ retain];
[userName release];
userName = userName_;
}
}
基本上,为了确保线程安全,原子版本必须锁定,并且还要触发对象的引用计数(以及autorelease计数以平衡它),以便确保对象存在于对象中,否则将存在如果另一个线程正在设置该值,则会导致竞争条件下降到0。
事实上,这些东西有很多不同的变体,取决于属性是标量值还是对象,以及保留,复制,只读,非原子等等如何相互作用。 一般来说,地产合成器只知道如何为所有组合“做正确的事情”。
原子
非原子
上一篇: What's the difference between the atomic and nonatomic attributes?
下一篇: What's the best way to communicate between view controllers?