在Objective-C我为什么要检查,如果自我= [超级初始化]不是零?(In Objective

2019-06-18 12:20发布

我对在Objective-C编写的init方法的普遍问题。

我看到它无处不在(苹果公司的代码,书籍,开放的源代码等)的init方法应该检查一下自我= [超级初始化]不与初始化,然后再继续为零。

对于一个init方法的默认模板,苹果是:

- (id) init
{
    self = [super init];

    if (self != nil)
    {
        // your code here
    }

    return self;
}

为什么?

我的意思是init曾经打算返回nil什么时候? 如果我呼吁NSObject的init和得到无回,则必须有所真的搞砸了吧? 而在这种情况下,你可能也不会写一个程序...

难道真的是常见的一类的init方法可能返回零? 如果是这样,在什么情况下,为什么?

Answer 1:

例如:

[[NSData alloc] initWithContentsOfFile:@"this/path/doesn't/exist/"];
[[NSImage alloc] initWithContentsOfFile:@"unsupportedFormat.sjt"];
[NSImage imageNamed:@"AnImageThatIsntInTheImageCache"];

... 等等。 (注:如果文件不存在的NSData可能会抛出异常)。 有相当多的地区,回访为零时出现了问题,因为这是标准的做法,以检查零几乎所有的时间,一致性的缘故预期的行为。



Answer 2:

这种特殊的成语是标准,因为它适用于所有情况。

虽然少见,会有情况下...

[super init];

...返回不同的实例,因此要求分配给自己。

而且会有情况下,它会返回nil,因此要求零检查,以便您的代码不会尝试初始化实例变量插槽不再存在。

底线是,它是使用记录正确的模式,如果你不使用它,你就错了。



Answer 3:

我认为,在大多数类,如果从[超级的init]的返回值是零,你选择了它的建议,标准的做法,然后返回过早,如果零,基本上你的应用程序仍然不会正常工作。 如果你想想看,即使是,如果(自我!=无)检查是存在的,为你的类的正常运行,你其实需要自我为非零99.99%的时间。 现在,假设,无论出于何种原因,[超级初始化] 回零,基本上你对零支票基本上把责任推到你的类,调用者在那里它可能会失败,反正,因为它自然会假定电话是成功的。

基本上,我得到的是,时间99.99%,如果在(自我!=无)不买任何东西更稳健性方面,因为你只是把责任推到你的调用。 要真正能够稳健地处理这个问题,你实际上需要把支票在您的整个调用层次。 即使如此,它会买你的唯一的事情是,你的应用程序将失败多一点清洁/强劲。 但它仍然会失败。

如果库班擅自决定以零回报为[超级初始化]的结果是,你几乎滚泥编不管怎么说,这是更多的指示,库类的作家提出的实施是一个错误。

我觉得这是比较旧式的编码建议,当应用程序在跑了很有限的内存。

但对C级代码,我仍然会通常检查的malloc()对NULL指针的返回值。 然而,对于Objective-C的,直到我找到相反的证据,我想我通常会跳过如果(自我!=无)检查。 为什么不一致?

因为,在C和malloc的水平,在某些情况下,你实际上可以部分恢复。 而我认为,在Objective-C,在例99.99%,如果[超级初始化]确实返回零,你基本上滚泥版,即使您尝试来处理它。 你还不如干脆让应用程序崩溃,并处理善后事宜。



Answer 4:

这是一种上述意见的摘要。

比方说,超收益nil 。 什么会发生?

如果你不遵守的规则

你的代码是在你中间会崩溃init方法。 (除非init什么都不做的意义)

如果按照惯例,不知道超可能会返回零(大多数人在这里结束)

您的代码是probalby在某一点后会崩溃,因为你的情况是nil ,在那里你预期不同的东西。 或者,你的程序会出人意料地表现得没有崩溃。 噢亲爱的! 你想要这个吗? 我不知道...

如果按照惯例,心甘情愿地让你的子类返回nil

您的代码文件应明确规定(!):“回报......或无”,和你的代码的其余部分需要被处理为此做好了准备。 现在,它是有道理的。



Answer 5:

通常情况下,如果你的类直接派生自NSObject ,你不会需要。 然而,这是一个很好的习惯进入,因为如果你的类从其他类派生,其初始化可能会返回nil ,如果是这样,你可以初始化,然后捕获和正常运行。

是的,备案,我按照最佳做法,并把它写在我的班,即使是那些直接从派生NSObject



Answer 6:

你说的没错,你可以经常只写[super init] ,但不会对一切事情的一个子类的工作。 人们更愿意只记住一个标准的代码行,并用它所有的时间,即使它只是有时必要的,因此,我们得到的标准if (self = [super init])这需要的零返回两者的可能性,比其他对象的可能性, self返回考虑。



Answer 7:

一个常见的错误是写

self = [[super alloc] init];

返回超类,这是不是你在子类的构造函数/初始化想要的东西的一个实例。 你回来的对象不以子类的方法,这可能会造成混淆响应,并生成有关不reponding的方法或标识符没有找到,等混乱的错误

self = [super init]; 

需要如果超类有成员(变量或其他对象)来建立子类成员之前初始化。 否则,objc运行时他们都初始化为0 。 ( 不像ANSI C,这往往分配的内存块而不清除它们在所有

是的,基类初始化失败可能是因为内存不足,错误,缺失的部分,资源获取故障等的所以零检查是明智的,只需不到几毫秒。



Answer 8:

这是为了检查intialazation工作,如果语句如果init方法没回零,所以它的一个方法来检查创建的对象工作正常返回true。 几个原因,我可以认为初始化的可能也许会失败的一个被覆盖的init方法的超类不知道的或类似的东西,我不会认为这是常见的,但。 但是,如果它确实发生,它能够更好没事发生碰撞我supose所以它总是检查...



Answer 9:

在OS X,它不是可能的-[NSObject init]失败由于内存的原因。 同样不能说的iOS。

此外,子类可能返回一个类时的书写好的做法nil因任何原因。



文章来源: In Objective-C why should I check if self = [super init] is not nil?