原子性(atomic)的实现机制:
会对属性的 setter/getter 方法进行加锁,这仅仅只能保证在 操作 setter/getter 方法是安全的。消耗性能,不能保证其他线程的安全
为什么不能保证绝对的线程安全?
例如 : 线程1 调用getter ,线程2 调用setter,线程3 调用setter,这3个线程并行同时开始,线程1会get到一个值,但是这个值不可控,可能是原始值,可能是线程2set的值,也可能是线程3set的值
验证:
@property(atomic, strong) NSString *name;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(test1) object:nil];
thread1.name = @"线程1";
[thread1 start];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(test2) object:nil];
thread2.name = @"线程2";
[thread2 start];
NSThread *thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(test3) object:nil];
thread3.name = @"线程3";
[thread3 start];
}
- (void)test1 {
NSLog(@"%@获取到name==%@",[NSThread currentThread].name,self.name);
}
- (void)test2 {
self.name = @"123";
}
- (void)test3 {
self.name = @"aaa";
}
多次触发touchesBegan方法,打印结果为:
2022-03-22 10:49:55.450401+0800 OC-Test[4955:83134] 线程1获取到name==(null)
2022-03-22 10:49:56.207614+0800 OC-Test[4955:83153] 线程1获取到name==aaa
2022-03-22 10:49:56.919238+0800 OC-Test[4955:83166] 线程1获取到name==123
2022-03-22 10:49:57.555077+0800 OC-Test[4955:83173] 线程1获取到name==123
2022-03-22 10:49:57.939385+0800 OC-Test[4955:83176] 线程1获取到name==aaa
非原子性(nonatomic):不使用同步锁,效率更高。
综上:由于atomic内部加锁开销较大,消耗性能,且不能绝对保证线程安全,所以通常使用nonatomic