【问题标题】:What happens if you don't nil-check [super init] and try to initialize nil?如果您不检查 [super init] 并尝试初始化 nil,会发生什么?
【发布时间】:2023-04-07 10:40:01
【问题描述】:

我知道之前已经讨论过这个问题,例如:In Objective-C why should I check if self = [super init] is not nil?

- (instancetype)init
{
    self = [super init];    // Is potentially nil

    if (self)
    {
        // Initialization code here…
    }

    return self;
}

我知道self 可能是nil,但这有什么关系呢?我看到的所有答案都只是说self 可能是nil,但没有解释为什么它很重要。如果您向nil 发送消息,则不会发生任何事情。您不会在任何其他代码中进行零检查(某些情况下除外),那么为什么需要在 init 中进行检查?

【问题讨论】:

  • You don't nil-check in any other code (except in some cases) - 这句话让我对你的未来感到害怕
  • @SimonMcLoughlin 在 Objective-C 中,除了init... 方法外,通常不会进行 nil-check。
  • @user3477950 一个是 Objective-c 开发人员,可以想到数百个检查 nil 的情况。仅仅因为它不会崩溃(并非在所有情况下),并不意味着 nil 是一个合适的接收值。向最终用户显示“(null)”是否合适?肯定不是
  • 除了@SimonMcLoughlin,我能想到的主要场景是你不想将 nil 存储在 NSArray 或 NSDictionary 中。
  • @user3477950 这样的cmets和态度导致代码和UI设计非常糟糕,期望世界永远适合你

标签: objective-c initialization null self super


【解决方案1】:

如果您向 nil 发送消息,则不会发生任何事情。

没错,因为运行时(信使函数)在实际调用方法之前会检查nil

但是,如果您将self 设置为nil 它在方法调用的中间,任何直接实例变量访问都会触发空指针取消引用:

self.myVar = ...;  // fine
_myVar = ...;     // fine

self = nil;

self.myVar = ...;  // fine
_myVar = ...;     // wrong

【讨论】:

  • @newacct Wain 的(错误和激进的)编辑引入了“例外”一词。我已经在答案的开头找到了这个词,但看起来我还没有找到第二个实例。 (我自己从未断言这将是一个异常,甚至不是段错误,因为它不是——取消引用空指针具有未定义的行为,我非常清楚,除非有人搞砸了我的帖子......)
  • 我不知道这个。在我自己尝试之前,我半信半疑。只是一个超酷的边缘案例。我说的是极端情况,因为您只能在“init 系列中的方法”中分配self,然后您必须放弃if(self) 检查。您可以从产生EXC_BAD_ACCESS 的地址中真正看到底层结构。感谢您的回答。
  • @NJones: "因为你只能在 ARC 中的 "init 系列中的方法" 中分配 self,即
【解决方案2】:

部分约定俗成,部分您是对的,但这确实取决于您要使用 self 进行设置。

在某些情况下,您会进行大量配置,而在实际不使用时创建所有这些配置是一种浪费。

在某些情况下,您可能会将 nil 传递给某些配置,当您这样做时会引发异常,因此检查而不进行调用是明智的。

遵循约定是安全且适当的方法,而且它确实不会花费您任何费用(它是由模板代码为您创建的)。

【讨论】:

  • 这并不容易,您只漏掉了#1 原因,即实例变量。 (出于某种模棱两可的原因,我收到了 2 票反对...)
猜你喜欢
  • 2021-04-04
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多