为啥将 [super init] 放在 if 语句中,因为无论返回是不是为 nil,我们还是返回它?

Posted

技术标签:

【中文标题】为啥将 [super init] 放在 if 语句中,因为无论返回是不是为 nil,我们还是返回它?【英文标题】:Why put [super init] inside of an if statement since whether or not the return is nil we return it anyway?为什么将 [super init] 放在 if 语句中,因为无论返回是否为 nil,我们还是返回它? 【发布时间】:2011-02-23 22:21:35 【问题描述】:

在 CS193p 课程中,他们说在 init 方法中应该有一个 if 语句来检查 [super init] 是否有效:

if (self = [super init]) 
    self.someProperty = parameter;    

return self;

不明白为什么会这样,好像[super init]返回nil,方法本身也会返回nil,不管if语句的结果如何?

编辑:问题是;为什么将self = [super init] 放在 if 语句中。 (不是:为什么有self = [super init]

【问题讨论】:

[[super alloc] init] 没有意义。你想要[super init] Why should I call self=[super init]的可能重复 是的,抱歉,我直接将它输入到 *** 中。我的问题是为什么要把它放在 if 语句中,不像你链接到的问题是为什么有它,所以请取消你的投票以结束。 该问题的接受答案包含您的问题的答案:“不。实例变量的访问相对于 self 指针 (...) self 显然必须指向正确的内存块。 @Bavarious:好的,但我不会说完全重复。 (详情:*** 作为搜索引擎的参考点) 【参考方案1】:

这是有道理的,因为在某些情况下 [super init] 可以返回 nil,在这种情况下,如果您尝试访问某个 ivar,您会崩溃。

例子:

-(id) init 
    self = [super init];
    some_ivar = [[NSObject alloc] init]; //compiler treats this as self->some_ivar
    //if self == nil you'll get EXC_BAD_ACCESS

    return self;

【讨论】:

【参考方案2】:

Apple 在Objective-c programming guide 中详细解释了这个特定概念。 (向下滚动到“处理初始化失败”部分)

但是 Apple 示例代码通常将自赋值保留在 if 语句之外

self = [super init];
if (self) 
    //init stuff...

return self;

如果您使用的是 LLVM 2.0 编译器,它会向您发出警告并告诉您也将语句括在括号中。像这样:

if ((self = [super init])) 
    //init stuff...

return self;

【讨论】:

【参考方案3】:

应该是if(self = [super init])...init 是一个实例方法,因此只能在已经被 alloc'd 的对象上调用。

【讨论】:

代码中的alloc是直接输入的时候出错,我现在已经修复了。【参考方案4】:

您需要调用 [super init] 以便超类可以执行它需要执行的任何一次性初始化。 init 方法返回一个表示已初始化对象的指针。

将 [super init] 的结果分配回 self 是标准的 Objective-C 约定。它是在超类作为其初始化工作的一部分返回与最初创建的对象不同的对象时完成的。例如,NSString 就是这样做的

所以它是 self = [super init]

我从未见过 [[super alloc] init],我一直使用 [super init],据我所知,这是惯例

【讨论】:

原来的会怎么样?【参考方案5】:

它不必在if 语句中。 你完全可以拥有它

self = [super init];
if ( self ) 
    self.someProperty = parameter;    

return self;

if 语句用于检查 self 是否已正确初始化并且可以安全地执行 self.someProperty = parameter

【讨论】:

当然self.someProperty = parameter 是完全安全的,因为它与[self setSomeProperty:parameter] 相同,您可以向 nil 对象发送消息。 并非如此。使用 nil 对象访问属性不会崩溃。同你发送 [nil_object someMethod]; @Max 我从没说过它会崩溃。 我认为“这样做是安全的……”意味着 我的意思更多的是“如果你这样做......它会产生预期的效果”,这意味着你确实有一个实例并且你的初始化代码将有效地初始化一些东西。【参考方案6】:

self = [[super alloc] init]; 创建一个基类 当您尝试调用仅子类的方法时,运行时会阻塞 稍后。

self = [super init]; 在 Objective-C 中很常见 当基类需要初始化变量值或实例化复合成员时, 否则它们将使用 Nil 或 (0) 值创建。

【讨论】:

以上是关于为啥将 [super init] 放在 if 语句中,因为无论返回是不是为 nil,我们还是返回它?的主要内容,如果未能解决你的问题,请参考以下文章

python中以下语句为啥会有两个__init__

为啥我不能在 Swift 中调用 UIViewController 上的默认 super.init()?

为啥允许在 Python 中使用 super 从 __init__ 返回一个值?

js面向对象为啥要init进行初始化?

为啥 super(MainWindow, self),__init__(*args, **kwargs) NameError: name '__init__' is not defined

iOS:UIView子类init会调用[super init]然后调用超类中的方法,为啥会调用[subclass initWithFrame:xx]?