1

文档指出,为了与在 MRR(手动保留释放)环境中编写的代码合作,在 ARC 环境中编写的代码不能具有以“new”开头的访问器名称,我无法弄清楚为什么 ARC 放这种对方法命名的限制。

4

1 回答 1

4

我相信原因是因为:

5.2.1。init 的语义

init 系列中的方法隐式使用它们的 self 参数并返回一个保留对象。这些属性都不能通过属性进行更改。

使用 self (可能是括号或强制转换)或 super 的接收器调用 init 方法称为委托 init 调用。除非从 init 方法进行委托 init 调用,并且不包括此类方法中的块,否则这是错误的。

作为通常规则的一个例外,变量 self 在 init 方法中是可变的,并且具有 __strong 变量的通常语义。但是,如果 init 方法在委托 init 调用完成后尝试使用之前的 self 值,则它是未定义的行为并且程序格式错误,不需要诊断。init 方法返回 self 是常规的,但不是必需的。

程序导致对同一对象的 init 方法进行两次或多次调用是未定义的行为,除非每个 init 方法调用最多执行一次委托 init 调用。

资料来源:http ://clang.llvm.org/docs/AutomaticReferenceCounting.html#family.semantics.init

过去,按惯例以new开头的方法名称用于调用 alloc 和 init 方法,我相信 Apple 的框架中仍然使用“new”约定的方法。我猜ARC在内存管理方面仍然考虑到这一点。

还阅读以下内容:http ://clang.llvm.org/docs/AutomaticReferenceCounting.html#family

一个 Objective-C 方法可能属于一个方法族,它是 Cocoa 约定赋予它的一组常规行为。

如果满足以下条件,则方法属于某个方法族:

  • 它有一个 objc_method_family 属性,将其放置在该族中;或者如果不是这样,
  • 它没有 objc_method_family 属性将其置于不同的族或没有族中,并且
  • 它的选择器属于相应的选择器系列,并且
  • 它的签名遵循方法族的附加限制。

如果忽略任何前导下划线,选择器的第一个组件完全由方法系列的名称组成,或者它以该名称开头后跟一个小写字母以外的字符,则选择器属于某个选择器系列。例如, _perform:with: 和 performWith: 将属于 perform 家族(如果我们认识的话),但 perform:with 不会。

这些家庭及其附加限制是:

  • alloc 方法必须返回可保留的对象指针类型。
  • 复制方法必须返回可保留的对象指针类型。
  • mutableCopy 方法必须返回一个可保留的对象指针类型。
  • 新方法必须返回可保留的对象指针类型。
  • init 方法必须是实例方法并且必须返回一个 Objective-C 指针类型。

此外,如果程序声明或包含对 init 方法的调用,该方法的返回类型既不是 id 也不是指向声明类的超类或子类的指针(如果该方法在类上声明) 或调用的静态接收器类型(如果它是在协议上声明的)。

我猜以上意味着您可以调用类似newobject而不是newObject的方法来避免 ARC 的机制,但这对于使用您的代码的任何人来说可能没有多大意义。也许您也可以通过在您的自定义new*方法上设置一个属性来避免通常的内存规则,该属性强制该属性上的一些其他方法系列。

于 2012-04-09T08:51:26.453 回答