在属性声明中,原子的和非原子的是什么意思
@property(非原子,保留)UITextField*用户名;
@属性(原子,保留)UITextField*用户名;
@属性(保留)UITextField*用户名;
这三者在操作上有什么不同
最后两个是相同的;“原子”是默认行为(请注意,它实际上不是一个关键字;它仅通过缺少来指定–非原子原子在最新版本的llvm/clang中作为关键字添加)
假设您正在@synthesis方法实现,原子与非原子会更改生成的代码。如果您正在编写自己的setter/getter,那么原子/非原子/保留/分配/复制只是建议。(注意:@synthesis现在是LLVM最新版本中的默认行为。也不需要声明实例变量;它们也将自动合成,并在名称前加上一个。,以防止意外直接访问)
使用“原子”,合成的setter/getter将确保始终从getter返回整值或由setter设置,而不管其他线程上的setter活动如何。也就是说,如果线程A在吸引子的中间,而线程B调用SETER,则一个实际的可行值——一个最有可能的自动对象——将在A/ 中返回给调用方。 在非原子中,不作此类保证。因此, “原子”没有做的是保证线程安全。如果线程A同时调用getter,而线程B和C使用不同的值调用setter,那么线程A可能会得到三个返回值中的任意一个——在调用任何setter之前的值,或者在B和C中传递给setter的值中的任何一个。同样,对象可能会以来自B或C的值结束,没办法说 确保数据完整性——多线程编程的主要挑战之一——是通过其他方式实现的 此外: 当多个依赖属性处于活动状态时,单个属性的原子性也不能保证线程安全 考虑: 在这种情况下,线程A可以通过调用 要解决这个问题,您需要一个事务模型。即,某些其他类型的同步和/或排除,允许在更新相关属性时排除对非原子的比“原子的”要快得多@property(原子,副本)NSString*firstName;
@属性(原子,副本)NSString*lastName;
@属性(只读、原子、副本)NSString*fullName;
setFirstName:然后调用setLastName:来重命名对象。同时,线程B可以在线程A的两次调用之间调用fullName,并将接收新的名字和旧的姓氏全名的访问