iOS 版 Objective-c/cocoa 中存在哪些方法系列?
我是一位经验丰富的开发人员,但对 iOS 开发(尤其是 iPhone)不太熟悉。我正在进行的一个项目正在使用自动引用计数(ARC)。
我正在对 ARC 进行一些研究,并发现了这个文档: http://clang.llvm.org/ docs/AutomaticReferenceCounting.html 并在标题为“保留返回值”的部分中指出,可以使用属性来指示调用者希望获得 +1 保留计数的所有权。它还继续指出,如果 ARC 检测到该属性位于特定方法系列中(具体名称为:alloc、copy、init、mutableCopy 和 new),那么 ARC 会自动将属性添加到方法中,
从进一步阅读来看,方法系列似乎只是简单的方法命名约定。我的理解是,如果方法名称以方法系列开头,那么它就在该方法系列中。例如,
+(id) init
+(id) initWithName:(NSString*)name
两者都是 init 方法系列的一部分。
我的问题是:是否有用于 iOS 开发的已定义方法族的正式列表?如果有,它们是什么/我可以在哪里找到它?
下面是我上面提到的 llvm.org 部分:
第 3.2.2 节:保留返回值状态:
返回可保留对象指针类型的函数或方法 可以被标记为返回保留值,表示 调用者希望获得 +1 保留计数的所有权。这是由 将 ns_returns_retained 属性添加到函数或方法 声明,如下所示:
id foo(void) __attribute((ns_returns_retained)); - (id) foo __attribute((ns_returns_retained));该属性是函数或方法类型的一部分。
当从这样的函数或方法返回时,ARC 保留该值 在返回语句的评估点,在离开所有之前 本地范围。
当从这样的函数或方法接收到返回结果时,ARC 释放它所包含的完整表达式末尾的值 内,服从本地值的通常优化。
理由:这使得被调用者的所有权直接转移正式化 给来电者。该模型最常见的场景是保留 从 init、alloc、new 和 copy 方法返回,但还有其他方法 框架中的案例。优化后一般不会有 需要额外的保留和释放。
alloc、copy、init、mutableCopy 和 new 系列中的方法是 隐式标记属性((ns_returns_retained))。这可能是 通过显式标记方法来抑制 属性((ns_returns_not_retained))。
如果 Objective-C 消息发送到的方法是未定义的行为 静态发送解析在其结果上具有不同的保留语义 从它动态解析到的方法。这是未定义的行为 如果通过静态类型进行块或函数调用 其执行结果有不同的保留语义 被调用的块或函数。
理由:与返回结果不匹配会导致过度保留或 过度释放,取决于方向。再次,关于规则 函数调用实际上只是现有 C/C++ 的应用 关于通过不兼容的函数类型调用函数的规则。
I am a experienced developer that is new to iOS developement (on iPhone in particular). A project I am working on is using Automatic Reference Counting (ARC).
I was doing some research on ARC and came across this document: http://clang.llvm.org/docs/AutomaticReferenceCounting.html and in a section titled: "Retained return values" it states that an attribute can be used to indicate that the caller expects to take ownership of a +1 retain count. It also goes on to state that ARC will automatically add the attribute to methods if it detects it is in particular method families (it specifically names: alloc, copy, init, mutableCopy, and new)
From further reading it seems that method families are simply method naming conventions. My understanding is that if the method name starts with a method family then it is in that method family. So for example
+(id) init
+(id) initWithName:(NSString*)name
are both part of the init method family.
My question is: Is there a formal list of defined Method Families for iOS development and if so, what are they / where might I find it?
below is the section llvm.org I mentioned above:
Section 3.2.2: Retained return values states:
A function or method which returns a retainable object pointer type
may be marked as returning a retained value, signifying that the
caller expects to take ownership of a +1 retain count. This is done by
adding the ns_returns_retained attribute to the function or method
declaration, like so:id foo(void) __attribute((ns_returns_retained));
- (id) foo __attribute((ns_returns_retained)); This attribute is part of the type of the function or method.When returning from such a function or method, ARC retains the value
at the point of evaluation of the return statement, before leaving all
local scopes.When receiving a return result from such a function or method, ARC
releases the value at the end of the full-expression it is contained
within, subject to the usual optimizations for local values.Rationale: this formalizes direct transfers of ownership from a callee
to a caller. The most common scenario this models is the retained
return from init, alloc, new, and copy methods, but there are other
cases in the frameworks. After optimization there are typically no
extra retains and releases required.Methods in the alloc, copy, init, mutableCopy, and new families are
implicitly marked attribute((ns_returns_retained)). This may be
suppressed by explicitly marking the method
attribute((ns_returns_not_retained)).It is undefined behavior if the method to which an Objective-C message
send statically resolves has different retain semantics on its result
from the method it dynamically resolves to. It is undefined behavior
if a block or function call is made through a static type with
different retain semantics on its result from the implementation of
the called block or function.Rationale: Mismatches with returned results will cause over-retains or
over-releases, depending on the direction. Again, the rule about
function calls is really just an application of the existing C/C++
rule about calling functions through an incompatible function type.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
查看有关 内存管理规则。看起来,你的列表很完整:“alloc”、“new”、“copy”或“mutableCopy”(只有 4 个关键字)。
Look at official Apple Developer documentation about Memory Management Rules. Seems, your list is complete: “alloc”, “new”, “copy”, or “mutableCopy” (only 4 keywords).
我将包括一些 Cocoa 类提供的便利构造函数:
它们都返回一个新的、自动释放的它们所发送到的类的实例 - 除了一些特殊情况,例如参见 @Peter Hosey 的评论。
我不知道是否有任何正式的规则,但模式是构造函数名称由类名组成,没有
NS
部分(并且没有Mutable
部分)对于可变类也是如此),后跟With:
和一个或多个参数。名称以小写字母开头(除了常见的字母,例如URLWithString:
)。例如,以下行提供了一个带有单个元素的自动释放的
NSArray
实例:I不知道编译器是否有什么特殊的规则来识别这种类型的构造函数。
I would include the convenience constructors provided by some Cocoa classes:
They all return a new, autoreleased instance of the class they are sent to - except for some special cases, see for instance @Peter Hosey's comment.
I don't know if there are any formal rules, but the pattern is that the constructor name is composed of the class name without the
NS
part (and without theMutable
part, too, for mutable classes) followed byWith<Parameter Type>:
and one or more parameters. The name begins with a lower case letter (except the usual suspects, likeURLWithString:
.)For instance, the following line provides an autoreleased
NSArray
instance with a single element:I don't know if there are any special rules in the compiler to recognize this type of constructor.
同一文档的第 5 节 标题为“方法系列”。它列出了所有当前定义的系列,即您在上面标识的系列;
alloc
、new
、copy
、mutableCopy
和init
。它还列出了成为该家庭成员的标准。大多数情况下,它仅基于方法名称,但也取决于返回类型。例如,copy
系列的成员必须返回一个对象;具有void
返回类型的复制方法不会被视为copy
方法系列的一部分。Section 5 of the same document is titled "Method Families". It lists all the currently defined families, which are the ones you identified above;
alloc
,new
,copy
,mutableCopy
, andinit
. It also lists the criteria for being part of that family. Mostly, it's just based on the method name, but it also depends on the return type. For example, a member of thecopy
family must return an object; a copy method that has avoid
return type will not be considered part of thecopy
method family.我不知道我是否见过正式的方法族列表,但你的分析基本上是正确的。我相信具有编译器强制语义的唯一方法命名约定是您帖子中提到的那些,即 alloc、init、copy(和 mutableCopy)和 new。即使在 ARC 之前/没有 ARC,Xcode 中包含的 clang 静态分析器也会使用这些命名约定来查找内存管理问题,并且它们也是 ARC 之前 Objective-C 程序员长期内存管理规则的基础。
也就是说,如果您使用以 init、copy、mutableCopy 或 new 开头的方法创建一个对象,那么您“拥有”该对象并负责稍后释放它。由具有任何其他名称的方法创建或返回的对象不归您(调用者)所有,如果您想保留对它们的引用,则必须保留它们。当您完成对象引用时,您所做的每个保留都必须由以后的释放来平衡。最后,对对象调用 autorelease 会将其放入最里面的自动释放池中。池负责稍后释放对象,其中稍后是在当前作用域之后的某个时间。因此,release 和 autorelease 都是放弃对象保留的有效方法。
现在,在 ARC 下,您(程序员)不应该(也不能)遵循我提出的规则。然而,ARC 本质上是一个系统,编译器在静态分析器的帮助下了解这些规则,并在编译时为您插入必要的内存管理调用。因此,如果您希望了解 ARC 在幕后所做的事情,那么了解这些规则是一个好的开始。
结果有点冗长,但重点是,您所命名的方法是我所知道的唯一在 Objective-C 中具有这种强制命名约定的方法,并且它源于上面提出的内存管理规则。当然,Objective-C 中还有其他命名约定,但它们是标准样式约定,不是在任何地方强制执行的。
I don't know that I've seen a formal list of method families, but your analysis is basically correct. I believe the only method naming conventions that have compiler-enforced semantics are those mentioned in your post, namely alloc, init, copy (and mutableCopy), and new. Even before/without ARC, the clang static analyzer included in Xcode uses those naming conventions to find memory management problems, and they're also the basis of the longstanding memory management rules for Objective-C programmers prior to ARC.
Namely, if you create an object using a method that begins with init, copy, mutableCopy or new, you "own" that object and are responsible for releasing it later. Objects created or returned by methods with any other name, are not owned by you, the caller, and if you want to keep a reference to them, you must retain them. Every retain you make must be balanced by a later release, when you're done with the object reference. Finally, calling autorelease on an object puts it in the innermost autorelease pool. The pool is responsible for releasing the object later, where later is sometime after the current scope. So, release and autorelease are both valid ways of relinquishing your retain on an object.
Now, the rules I've set forth shouldn't (and can't) be followed by you, the programmer, under ARC. However, ARC is essentially a system whereby the compiler with help from the static analyzer knows these rules and inserts the necessary memory management calls for you at compile time. So, if you're looking to develop an understanding of what ARC is doing behind-the-scenes, understanding these rules is a good start.
This turned out a bit longwinded, but the point is that the methods you've named are the only ones I know of that have this enforced naming convention in Objective-C, and it stems from the memory management rules set forth above. There are other naming conventions in Objective-C, to be sure, but they're standard style conventions, not something that's enforced anywhere.