10

在 Objective-C 中声明属性时,可以配置哪些自定义选项,这些选项定义了访问器方法的行为方式?

例如,你可以有弱、强、只读。

4

1 回答 1

41

这是简短的答案:

atomic vs nonatomic主要确保从合成的 getter 返回完整的值,并确保完整的值由合成的 setter 写入。

readwrite 与 readonly确定合成属性是否具有合成访问器(readwrite 有一个 setter 并且是默认值,readonly 没有)。

分配 vs 弱 vs 保留 vs 复制决定了合成访问器如何与 Objective-C 内存管理方案交互。

现在是长答案:

原子与非原子

假设您正在 @synthesizing 方法实现,原子与非原子会更改生成的代码。如果您正在编写自己的 setter/getter,则 atomic/nonatomic/retain/assign/copy 只是建议性的。

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

在非原子中,没有这样的保证。因此,非原子比原子快得多。

atomic 不做的是对线程安全做出任何保证。如果线程 A 同时调用 getter,而线程 B 和 C 使用不同的值调用 setter,则线程 A 可能会返回三个值中的任何一个——在调用任何 setter 之前的那个值或传递给 setter 的值中的任何一个在 B 和 C 中。同样,对象可能以 B 或 C 中的值结束,无法判断。

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

分配、弱化、保留、复制

简而言之,assign vs weak vs retain vs copy 决定了合成访问器如何与 Objective-C 内存管理方案交互:

  • assign 是默认值,只是执行变量赋值。它不声明所有权,因此如果没有其他人通过保留或其他方式声明所有权,则属性指针指向的对象可能随时消失。在 ARC 环境中,assign 并不能确保指针不会悬空,这意味着如果另一侧的对象已被释放,则指针可能最终指向垃圾。
  • weak 与 assign 相同,只是它将导致释放对象的指针清零以阻止它们悬空。Weak 仅在 ARC 环境中可用。
  • 保留指定应发送新值 - 保留分配和旧值发送释放。保留也被称为强大。
  • 复制指定应发送新值 - 分配时复制并发送旧值释放。Copy 通常用于属性类型具有可变表亲 (NSArray/NSMutableArray) 的属性,以防止其他人发送可变版本并更改它们/让它们在背后更改等等。

请记住,保留/强是在创建的对象上完成的(它增加了引用计数),而复制创建了一个新对象。那么,区别在于您是要向对象添加另一个保留还是创建一个全新的对象。

于 2012-09-12T04:25:02.567 回答