ios – 原子和非原子属性之间有什么区别?

财产申报中的含义atomicnonatomic含义是什么?

@property(nonatomic, retain) UITextField *userName;
@property(atomic, retain) UITextField *userName;
@property(retain) UITextField *userName;

这三者之间的运作区别是什么?


最后两个是相同的; “atomic”是默认行为(注意它实际上不是一个关键字;它仅在没有的情况下指定nonatomic – atomic在最近版本的llvm / clang中被添加为关键字)。

假设你是@synthesizing方法实现,原子与非原子会改变生成的代码。如果您正在编写自己的setter / getter,则atomic / nonatomic / retain / assign / copy仅仅是建议性的。(注意:@synthesize现在是LLVM的最新版本中的默认行为。也没有必要声明实例变量;它们也将自动合成,并且将_在其名称前加上以防止意外直接访问)。

对于“原子”,合成的setter / getter将确保始终从getter返回整个值或由setter设置,而不管任何其他线程上的setter活动。也就是说,如果线程A位于getter的中间,而线程B调用setter,则实际可行的值 – 一个自动释放的对象,很可能 – 将返回给A中的调用者。

nonatomic,没有这样的保证。因此,nonatomic比“原子”快得多。

什么“原子”并没有做的就是关于线程安全的任何保证。如果线程A与线程B同时调用getter并且C调用具有不同值的setter,则线程A可以获得返回的三个值中的任何一个 – 在调用任何setter之前的值或者传递给setter的任一值在B和C中。同样,对象可能最终得到B或C的值,无法分辨。

确保数据完整性 – 多线程编程的主要挑战之一 – 是通过其他方式实现的。

添加到此:

atomicity 当多个依赖属性在起作用时,单个属性也不能保证线程安全。

考虑:

 @property(atomic, copy) NSString *firstName;
 @property(atomic, copy) NSString *lastName;
 @property(readonly, atomic, copy) NSString *fullName;

在这种情况下,线程A可以通过调用setFirstName:然后调用来重命名对象setLastName:。同时,线程B可以fullName在线程A的两个调用之间调用,并且将接收与旧的姓氏一起的新的名字。

要解决此问题,您需要一个事务模型。即一些其他类型的同步和/或排除,允许fullName在更新依赖属性时排除对访问。


这在Apple的文档中有解释,但下面是实际发生的一些示例。请注意,没有“atomic”关键字,如果未指定“nonatomic”,则属性为atomic,但明确指定“atomic”将导致错误。

//@property(nonatomic, retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    return userName;
}

- (void) setUserName:(UITextField *)userName_ {
    [userName_ retain];
    [userName release];
    userName = userName_;
}

现在,原子变体有点复杂:

//@property(retain) UITextField *userName;
//Generates roughly

- (UITextField *) userName {
    UITextField *retval = nil;
    @synchronized(self) {
        retval = [[userName retain] autorelease];
    }
    return retval;
}

- (void) setUserName:(UITextField *)userName_ {
    @synchronized(self) {
      [userName_ retain];
      [userName release];
      userName = userName_;
    }
}

基本上,原子版本必须采取锁定以保证线程安全,并且还会碰撞对象的引用计数(以及自动释放计数以平衡它),以便保证对象存在对象,否则存在如果另一个线程正在设置该值,则是一个潜在的竞争条件,导致引用计数降至0。

根据属性是标量值还是对象,以及如何保留,复制,只读,非原子等交互,实际上有很多不同的变体如何工作。一般来说,属性合成器只知道如何为所有组合做“正确的事”。

添加评论

友情链接:蝴蝶教程