【问题标题】: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]。
  • 是的,抱歉,我直接将它输入到 stackoverflow 中。我的问题是为什么要把它放在 if 语句中,不像你链接到的问题是为什么有它,所以请取消你的投票以结束。
  • 该问题的接受答案包含您的问题的答案:“不。实例变量的访问相对于 self 指针 (...) self 显然必须指向正确的内存块。
  • @Bavarious:好的,但我不会说完全重复。 (详情:Stackoverflow 作为搜索引擎的参考点)

标签: iphone objective-c


【解决方案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) 值创建。

      【讨论】:

        猜你喜欢
        • 2011-10-07
        • 1970-01-01
        • 2021-12-21
        • 1970-01-01
        • 2016-02-15
        • 2013-03-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多