关于C#:’atomic’ and non-atomic有什么区别?

What's the difference between 'atomic' and non-atomic?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Atomic vs nonatomic properties

我只想知道这两行代码有什么不同:

1
@property(nonatomic, retain) NSString *str;

1
@property(atomic, retain) NSString *str;

桑克斯当做,TEK3


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

考虑一下get访问器的幼稚实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@interface MyObject : NSObject
{
    id myPropertyIVar;
}
-(id) myProperty;

@end

@implementation MyObject

-(id) myProperty
{
    return myPropertyIvar;
}

// other stuff

@end

这很好,除非在保留-myproperty返回的值之前释放myObject实例,否则很可能会释放返回的值。因此,更安全的方法是实现-myproperty,如下所示:

1
2
3
4
-(id) myProperty
{
    return [[myPropertyIvar retain] autorelease];
}

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

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

  • myObject的实例由另一个线程释放和释放,从而导致释放和释放ivar。
  • MyProperty被另一个线程重新分配,导致旧版本被释放和释放。

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

1
2
3
4
5
6
-(id) myProperty
{
    // lock
    return [[myPropertyIvar retain] autorelease];
    // unlock
}

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


苹果文档很好地解释了这一切。要了解属性,包括其原子性,请阅读本页。