【问题标题】:What's the difference between 'atomic' and non-atomic? [duplicate]“原子”和非原子之间有什么区别? [复制]
【发布时间】:2011-03-20 22:05:09
【问题描述】:

可能重复:
Atomic vs nonatomic properties

我只是想知道这两行代码有什么区别:

@property(nonatomic, retain) NSString *str;

@property(atomic, retain) NSString *str;

谢谢, 问候, tek3

【问题讨论】:

标签: objective-c


【解决方案1】:

在引用计数的多线程环境中,原子属性是必需的,以便在线程有机会保留对象之前阻止对象消失。

考虑 get 访问器的简单实现:

@interface MyObject : NSObject 
{
    id myPropertyIVar;
}
-(id) myProperty;

@end

@implementation MyObject

-(id) myProperty
{
    return myPropertyIvar;
}

// other stuff

@end

这一切都很好,除了如果您在保留来自 -myProperty 的返回值之前释放 MyObject 的实例,则返回的值很可能会被释放。因此,像这样实现 -myProperty 会更安全:

-(id) myProperty
{
    return [[myPropertyIvar retain] autorelease];
}

现在这在单线程环境中是完全安全的。

不幸的是,在多线程环境中存在竞争条件。如果线程在保留增加保留计数之前的任何时间被中断,以下任一情况都会导致您收到垃圾指针:

  • MyObject 的实例被另一个线程释放和释放,导致 ivar 被释放和释放
  • myProperty 被另一个线程重新分配,导致旧版本被释放和释放

因此,对属性的所有访问都必须受到锁的保护。 get 访问器看起来像这样。

-(id) myProperty
{
    // lock
    return [[myPropertyIvar retain] autorelease];
    // unlock
}

set 访问器受到类似保护,-dealloc 中的释放也是如此

【讨论】:

  • 非常感谢 JeremyP。我真的从你的回答中学到了很多。
  • 不是完整的故事。 :) 原子属性实际上并不能保证线程安全。它只保证您将获得/设置一个整数值。
  • @bbum:哈,我知道我也应该把那一点放进去。在我的辩护中,你会注意到我什至没有声称原子属性保证线程安全,只是它使得在多线程环境中安全地获取属性成为可能
【解决方案2】:

Apple 文档很好地解释了这一切。要了解属性,包括它们的原子性,请阅读this page

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 2015-08-18
  • 2019-05-04
  • 2012-10-03
  • 2017-07-04
  • 1970-01-01
  • 2011-10-28
相关资源
最近更新 更多