【问题标题】:What happens if we don't check for "if (self)" in init methods? [duplicate]如果我们不在 init 方法中检查“if (self)”会发生什么? [复制]
【发布时间】:2014-05-01 18:03:46
【问题描述】:

我开始查看我们学长做的代码,发现init方法总是有代码-(id)init方法。他们通过以下方式使用代码。以下代码用于所有 viewController。

    self = [super initWithNibName:@"ViewController" bundle:[NSBundle mainBundle]];
    return self;

这部分if(self)self有什么用?

    //And in some viewcontroller contains.
    self = [super initWithNibName:@"ViewController" bundle:[NSBundle mainBundle]];
    if (self) {
        //Do some stuff
    }
    return self;

【问题讨论】:

  • @Amar,我问的是 if(self) 和 without if(self)
  • 不做self检查是错误的。没有解释,IMO。
  • @Amar,self = [super initWithNibName:@"ViewController" bundle:[NSBundle mainBundle]];返回自我;
  • 太糊涂了,问前辈这个问题?害怕失业?
  • Amar,不,不需要在上面的代码中进行自我检查,因为在他的示例中没有使用 self 引起问题。大多数答案都有更好的解释。

标签: ios objective-c self


【解决方案1】:

当您在方法中访问实例变量时,代码相当于通过自指针寻址它们:

- (void)method {
  iVar = 1;
  // actually the following line will be executed:
  self->iVar = 1;
}

因此,如果由于某种原因 self 指针为 nil,并且您在 init 方法中访问您的 ivars,您的应用程序将崩溃,因为您将尝试取消对空指针的引用。例如以下简单示例将崩溃:

@implementation TestObj {
  int a;
}

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

  a = 1; // Crash
  return self;
}
@end

此外,如果您的 [super init] 方法因任何原因返回 nil,这可能表明出现问题,您不应继续进行对象初始化和任何其他所需的工作。

【讨论】:

  • +1,代表self->iVar 部分。
【解决方案2】:

关于检查自身是否存在的代码:

if (self) {
   //Do some stuff
}
return self;

仅当您想设置初始属性值时才需要。这就是为什么会有评论

// Do some stuff

如果您不打算为变量或属性设置任何初始值,则无需检查 self 并且可以立即return self

【讨论】:

  • 如果你没有初始化任何东西,不要覆盖init
【解决方案3】:

if (self) 正在检查对 super 的调用是否在初始化后实际上返回了一个对象。如果出现问题,继续下去是没有意义的,而且还会产生运行时错误。

请记住,init 方法应该初始化您正在为其创建类的类型的对象,并返回该对象。您的 init 方法覆盖了 super 方法,这就是您调用 super 的原因,以便首先运行来自 Apple 的代码,然后您对从 init 方法返回的对象(即 UIViewController)执行一些操作。

那么,当然,你的 init 方法也必须返回那个对象(self)。

【讨论】:

    【解决方案4】:

    [super initWith...] 方法总是有可能失败,因此返回一个为 nil 的 self,因为它没有被创建。

    在这种情况下,最好先测试self 是否已正确初始化,然后再对其进行操作。

    if (self) 实际上是if (self != nil) 的“快捷方式”,因为任何有效的对象都将有一个非空的内存地址,因此if 测试将在任何不同于 0(空)的情况下成功。

    【讨论】:

      【解决方案5】:

      if(self) 正在检查以确保 'self' 在实际开始对其执行操作之前存在。

      self 是一个对象,所以如果它不存在,那么 self 将是未定义的,if(self) 将评估为 false,跳过代码块。

      【讨论】:

      • 这是不正确的。 super 调用将返回对象或 nil,仅此而已(否则您的应用程序无论如何都会严重损坏)。并且还允许在 nil 对象上调用消息(它们什么都不做)。查看几乎所有正确答案的其他答案。
      • “super init”方法可以而且经常会返回一个与传入的对象不同的不同对象。你不能对结果做任何假设。
      • 是的,但它不是 celem 声称的“未定义”。此外,问题是“如果会发生什么”,这个答案根本没有回答这个问题。它更确切地说回答了“检查自我做什么?”的问题。我对此答案投了反对票并添加了一个解释,尽管我现在发现我做得不够准确。
      猜你喜欢
      • 1970-01-01
      • 2023-04-07
      • 2012-01-13
      • 1970-01-01
      • 2011-03-04
      • 2019-12-04
      • 2016-07-10
      • 1970-01-01
      • 2014-03-27
      相关资源
      最近更新 更多