拥有便利的构造函数类方法有两个原因。第一个是,这个习语[[Thing alloc] initWithFoo: xyz]
很常见,但不方便在任何地方输入。所以,[Thing thingWithFoo: xzy]
是一个常见的缩写。
更深层次的原因与引用计数有关。以 开头的方法init
应该返回实例的引用,其所有权转移给调用者。而便利类方法通常返回autorelease
d 引用:
+ (id)packetWithType:(PacketType)packetType
{
return [[[[self class] alloc] initWithType:packetType] autorelease];
}
为了避免悬空引用和/或内存泄漏,了解这一点很重要:
Thing* thing = [[Thing alloc] initWithFoo: xyz];
// Now, *I* own the reference and *I* am responsible for releasing
// it, when I no longer need it.
[thing release]
另一方面,由返回的引用
Thing* thing = [Thing thingWithFoo: xyz];
由“最近的”拥有NSAutoreleasePool
。调用者不负责释放它(事实上,那是错误的!)。如果要保留引用,调用者必须retain
在此处实际使用它:
self->myMember = [thing retain];
即使在使用 ARC 时,您也应该了解这些约定,因为基本规则仍然有效,即使(在 ARC 下)是编译器生成遵守它们的代码。首NARC
字母缩略词是一种很好的记忆方式,哪些方法名称前缀具有某些职责。这个答案有细节。