V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
iOS 开发实用技术导航
NSHipster 中文版
http://nshipster.cn/
cocos2d 开源 2D 游戏引擎
http://www.cocos2d-iphone.org/
CocoaPods
http://cocoapods.org/
Google Analytics for Mobile 统计解决方案
http://code.google.com/mobile/analytics/
WWDC
https://developer.apple.com/wwdc/
Design Guides and Resources
https://developer.apple.com/design/
Transcripts of WWDC sessions
http://asciiwwdc.com
Cocoa with Love
http://cocoawithlove.com/
Cocoa Dev Central
http://cocoadevcentral.com/
NSHipster
http://nshipster.com/
Style Guides
Google Objective-C Style Guide
NYTimes Objective-C Style Guide
Useful Tools and Services
Charles Web Debugging Proxy
Smore
UtopiaCHN
V2EX  ›  iDev

Objective-C 中 getter 有保证原子性( atomic)的必要吗?(换句话说 getter 有保证线程安全的必要吗)

  •  
  •   UtopiaCHN · 2015-12-05 19:02:45 +08:00 · 2606 次点击
    这是一个创建于 3278 天前的主题,其中的信息可能已经有所发展或是发生改变。

    @property 设置 atomic 时,同时对 setter 和 getter 生效。 setter 作用是设置值,保证线程安全可以理解。因为如果 A 线程在设值,那么后来的 B 线程应该等待 A 线程设置完成后再去设置。但是 getter 的作用是获取值,好像没有保证线程安全的必要吧?直接获取不就好了。

    11 条回复    2015-12-05 20:46:55 +08:00
    11
        1
    11  
       2015-12-05 19:19:22 +08:00
    atomic 不保证线程安全
    UtopiaCHN
        2
    UtopiaCHN  
    OP
       2015-12-05 19:21:10 +08:00
    @11 atomic 不保证整个对象的线程安全,但是它保证 setter 和 getter 各自的线程安全啊
    11
        3
    11  
       2015-12-05 19:25:21 +08:00
    @UtopiaCHN getter 的话,如果在两个线程都进行 getter ,那不能保证获取的数据一致啊
    UtopiaCHN
        4
    UtopiaCHN  
    OP
       2015-12-05 19:27:09 +08:00
    @11 你是指有另一个线程在 setter 的时候吗?
    11
        5
    11  
       2015-12-05 19:29:56 +08:00
    @UtopiaCHN 对呀
    UtopiaCHN
        6
    UtopiaCHN  
    OP
       2015-12-05 19:34:33 +08:00
    @11 如果 A 线程在 getter ,然后 B 线程去 setter ( A 线程直到 B 线程结束后才结束),那么 A 线程得到的是 B 线程设置之前还是之后的值呢
    jjgod
        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 ,要么是设置后的。
    UtopiaCHN
        8
    UtopiaCHN  
    OP
       2015-12-05 20:20:57 +08:00
    @jjgod 非常感谢。 getter 和 setter 虽然是名词容器的意思,但是它们还是要完成相应的操作。你的解释完全符合原子性的定义。我的理解是不是错误的--“如果 A 线程在设值,那么后来的 B 线程应该等待 A 线程设置完成后再去设置。”,我理解的好像是加锁的意思,按照我的理解,不能同时有两个线程并发访问 setter 和 getter ,事实上是可以并发访问的对吗?
    UtopiaCHN
        9
    UtopiaCHN  
    OP
       2015-12-05 20:26:40 +08:00
    @jjgod 大神你在 Apple 工作啊,好厉害,膜拜。
    UtopiaCHN
        10
    UtopiaCHN  
    OP
       2015-12-05 20:35:04 +08:00
    @jjgod 那个应该是访问器,写错了。如果只是单纯的原子性,那么这好像不属于线程安全吧?也就是说 atomic 不能保证 setter 和 getter 的线程安全,只有加锁才可以。
    jjgod
        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 值。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1814 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 16:33 · PVG 00:33 · LAX 08:33 · JFK 11:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.