主要区别
系统生成的setter/getter
方法不一样
atomic
生成的方法有加锁操作
nonatomic
生成的方法不加锁
atomic
加锁操作只保证了setter/getter
的存取方法的线程安全
线程1执行了某属性setter
方法,执行到一半.线程2调用getter
方法.那么会执行完setter
方法,再执行getter
方法,线程2拿到的是线程1setter
之后的完整值
**但是,**当几个线程同时调用setter,getter
方法时,会get
到一个完整的值,可这个值不可控,可能是没set
之前的原始值,也可能是某个线程set
之后的值:
线程1:getter
线程2:setter
线程3:setter
…
atomic
线程安全是不准确的,atomic
只是对setter
和getter
方法进行了加锁操作,只是读取安全,并非真正意义上的线程安全.(假如线程1在set/get
时,线程2执行release
操作,可能就会crash
)
nonatomic
系统生成的setter/getter
方法没有加锁操作
线程不安全,但更快
当多个线程同时访问时,会出现无法预料的结果
伪代码演示实现
@property (nonatomic, strong) UIView *view;
@property (atomic, strong) UIView *view1;
nonatomic
的setter/getter
方法实现:
@synthesize view = _view;
//set
- (void)setView:(UIView *)view {
if (_view != view) {
[_view release];
_view = [view retain];
}
}
//get
- (UIView *)view {
return _view;
}
atomic
的setter/getter
方法实现:
@synthesize view1 = _view1;
//set
- (void)setView1:(UIView *)view1 {
//同步代码块
@synchronized(self) {
if (_view1 != view1) {
[_view1 release];
_view1 = [view1 retain];
}
}
}
//get
- (UIView *)view1 {
UIView *view = nil;
//同步代码块
@synchronized(self) {
view = [[_view1 retain] autorelease];
}
return view;
}
总结
atomic
只保证了存取方法的线程安全,不能保证对象的线程安全.在对线程中,需要开发者自己来处理线程安全.
atomic
生成的setter
和getter
方法线程安全,但相对于nonatomic
,它更耗资源,速度慢.所以大多数情况下使用nonatomic
.