@property 设置 atomic 时,同时对 setter 和 getter 生效。 setter 作用是设置值,保证线程安全可以理解。因为如果 A 线程在设值,那么后来的 B 线程应该等待 A 线程设置完成后再去设置。但是 getter 的作用是获取值,好像没有保证线程安全的必要吧?直接获取不就好了。
1
11 2015-12-05 19:19:22 +08:00
atomic 不保证线程安全
|
6
UtopiaCHN OP @11 如果 A 线程在 getter ,然后 B 线程去 setter ( A 线程直到 B 线程结束后才结束),那么 A 线程得到的是 B 线程设置之前还是之后的值呢
|
7
jjgod 2015-12-05 19:59:09 +08:00
@UtopiaCHN: 首先, getter 和 setter 是名词,不要把它们作动词用, get 和 set 才是动词,相信你小学英语学过。
至于你的问题, atomic 是不作这种保证的,它只保证得到的不是 B 线程设置了一半的值。比如假设一个 nonatomic 的 property 返回一个 CGPoint , B 线程设置了这个 point 的 .x 就切换回 A 线程了, A 线程最后返回的就可能是一半新的 .x 和一半旧的 .y , atomic 避免的是这种情况,保证你要么得到的是 B 设置前的那个 CGPoint ,要么是设置后的。 |
8
UtopiaCHN OP @jjgod 非常感谢。 getter 和 setter 虽然是名词容器的意思,但是它们还是要完成相应的操作。你的解释完全符合原子性的定义。我的理解是不是错误的--“如果 A 线程在设值,那么后来的 B 线程应该等待 A 线程设置完成后再去设置。”,我理解的好像是加锁的意思,按照我的理解,不能同时有两个线程并发访问 setter 和 getter ,事实上是可以并发访问的对吗?
|
10
UtopiaCHN OP @jjgod 那个应该是访问器,写错了。如果只是单纯的原子性,那么这好像不属于线程安全吧?也就是说 atomic 不能保证 setter 和 getter 的线程安全,只有加锁才可以。
|
11
jjgod 2015-12-05 20:46:55 +08:00
看这里的第一个和第二个回复吧: http://stackoverflow.com/questions/588866/whats-the-difference-between-the-atomic-and-nonatomic-attributes
比如这个等价为 atomic property 生成代码的例子: - (UITextField *) userName { UITextField *retval = nil; @synchronized(self) { retval = [[userName retain] autorelease]; } return retval; } - (void) setUserName:(UITextField *)userName_ { @synchronized(self) { [userName release]; userName = [userName_ retain]; } } 比如 A 线程在先执行到 `UITextField *retval = nil` 这一步,切换到线程 B ,然后线程 B 执行完了跳回线程 A ,那么 A 是会读取到新的 userName instance variable 并返回的,但是假如一开始 A 是执行到 `return retval` 之前再切换到 B 呢,返回的就还是 B 设置前的 userName 值。 |