这是Objective-C中常见的习语。
我只看到[[NSImage alloc] initWithContentsOfFile:str]上使用它,它总是让我觉得存在内存泄漏,因为我调用了alloc而且口头禅是: “调用alloc,你必须调用release” - 除非是你不需要的情况之一。
答案 0 :(得分:6)
在初始化对象时指示错误是一种常见的习惯用法。你是对的,但必须释放分配的实例。所以模式将是
- (id)init
{
self = [super init];
if(self != nil) {
//... do init
if(errorInInit) {
[self release];
return nil;
}
}
return self;
}
答案 1 :(得分:0)
有关init方法的更多问题和解答,请参阅using alloc and init。
也接受args(例如:initWithXxx:(Xxx*)x
,例如NSString
的{{1}})的init方法可以返回initWithBytes:
而无需调用nil
if(例如,它不喜欢它收到的arg。 init方法必须像任何方法一样管理内存。只是init有一些不寻常的行为,即返回其[super init]
或返回其他对象,因为它选择了。一般来说,这并不是很多。
答案 2 :(得分:0)
关于这个主题的两个后续问题,我还没有看到明确的答案 - 现在在自己的问题中重复,Followup to returning nil from a [[class alloc] init]
1:如果init在调用super之前失败了某些先决条件,该怎么办?例如,假设在这个initWithStuff:方法中传递nil或者通常没有值传递给initWithValue:绝对失败,我们肯定想要返回nil。
- (id)initWithStuff:(Stuff *)inStuff {
if (!inStuff || ![inStuff hasValidValue])
{
// can't proceed to call initWithValue: because we have no value
// so do what?
return nil;
}
NSInteger value = [inStuff integerValue];
return [super initWithValue:value];
}
也许一个更清晰的例子是,如果我们包装的指定初始化方法接受一个对象指针,并且如果它传递了nil则抛出异常。我们肯定需要将导致异常的init调用短路。
我的猜测:以任何可能的方式初始化,然后在返回nil之前释放self。如有必要,请调用裸init或任何其他初始化程序,以便在释放之前完成将self置于已知状态。
// can't proceed to call super's initWithValue: because we have no value
// so do what? do this:
self = [super init]; // or initWithValue:0
[self release];
return nil;
如果没有这样的初始化器可以在没有有效数据的情况下工作,我想有人需要构建一些有效的伪数据。或者向其作者抱怨,直到那时只返回零并与泄漏一起生活:^)
2:ARC如何影响这种情况?
我的猜测:仍然以任何可能的方式完成初始化,然后返回零。你认为设置自我可能是多余的,但在某些情况下并非如此。在任何情况下,它都需要在那里使编译器警告静音。
// can't proceed to call super's initWithValue: because we have no value
// so do what? do this:
self = [super init]; // finish init so ARC can release it having no strong references
return nil;