+ (id)packetWithType:(PacketType)packetType
{
return [[[self class] alloc] initWithType:packetType];
}
- (id)initWithType:(PacketType)packetType
{
if ((self = [super init]))
{
// code
}
return self;
}
Run Code Online (Sandbox Code Playgroud)
为什么我们需要第一类方法,不是第二个就足够初始化了?
有方便的构造函数类方法有两个原因.第一个是,成语[[Thing alloc] initWithFoo: xyz]
很常见,但不方便在任何地方打字.所以,[Thing thingWithFoo: xzy]
是一个常见的缩写.
更深层次的原因与引用计数有关.以#开头的方法init
应该返回实例的引用,其所有权转移给调用者.方便类方法通常返回autorelease
d引用:
+ (id)packetWithType:(PacketType)packetType
{
return [[[[self class] alloc] initWithType:packetType] autorelease];
}
Run Code Online (Sandbox Code Playgroud)
知道这一点很重要,以避免悬空引用和/或内存泄漏:
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]
Run Code Online (Sandbox Code Playgroud)
另一方面,返回的引用
Thing* thing = [Thing thingWithFoo: xyz];
Run Code Online (Sandbox Code Playgroud)
由"最近的"拥有NSAutoreleasePool
.调用者不负责释放它(事实上,这是错误的!).如果要保留引用,则调用者必须retain
在此处实际显示:
self->myMember = [thing retain];
Run Code Online (Sandbox Code Playgroud)
即使使用ARC,您也应该了解这些约定,因为基础规则仍然有效,即使(在ARC下)它是编译器,它生成代码来遵守它们.的NARC
缩写,是一个很好的方式来记住,该方法的名称前缀配备一定的责任.这个答案有详细说明.
归档时间: |
|
查看次数: |
634 次 |
最近记录: |