'原子'和非原子之间有什么区别?

tek*_*ek3 8 objective-c

可能重复:
原子与非原子属性

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

@property(nonatomic, retain) NSString *str;
Run Code Online (Sandbox Code Playgroud)

@property(atomic, retain) NSString *str;
Run Code Online (Sandbox Code Playgroud)

Thanx,问候,tek3

Jer*_*myP 8

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

考虑一下get访问器的天真实现:

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

@end

@implementation MyObject

-(id) myProperty
{
    return myPropertyIvar;
}

// other stuff

@end
Run Code Online (Sandbox Code Playgroud)

这一切都很好,但是如果在保留-myProperty的返回值之前释放MyObject实例,则可能会释放返回的值.因此,像这样实现-myProperty更安全:

-(id) myProperty
{
    return [[myPropertyIvar retain] autorelease];
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

-(id) myProperty
{
    // lock
    return [[myPropertyIvar retain] autorelease];
    // unlock
}
Run Code Online (Sandbox Code Playgroud)

set访问器同样受到保护,-dealloc中的版本也是如此