viewDidLoad被提前调用

本文探讨了iOS开发中一个不为人知的现象:在特定条件下viewDidLoad方法的提前调用导致的执行顺序问题。该问题使得视图控制器内的成员变量在初始化前就被访问,引发程序逻辑错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天写项目的时候发现了一个非常奇怪的问题,我一度认为可能是我的 Xcode 出了 bug。

先来猜猜下面代码的执行顺序?



这是一段非常常见的代码,很多 controller 都是这么写的。

正常来说执行顺序肯定是 1、2、3、4 无疑。然而事实上,执行顺序却是:1、3、4、2。


这就导致了一个问题:viewModel 请求不到数据,因为走到第 4 步的时候,viewModel 还没有被初始化,此时它是 nil。

如下图所示:



从控制台中我们可以看到,最下面的 _viewModel = nil。而且当走完第 4 步后,程序竟然又回到了第 2 步。

起初我以为这是一个 Xcode 本身的 bug,因为它实在是太奇怪了。后来我才知道,原来是因为 viewDidLoad 被提前调用了。


viewDidLoad 方法一般只会在 nib 文件已载入内存,也就是视图树构建完成之后调用。

但是如果 controller 的 view 属性被使用时为 nil,就会导致 nib 的加载,从而导致 viewDidLoad 的调用。


对于本文来说,我们在初始化方法中写了 self.view.backgroundColor = xxx; 这句话本身并没有任何错误,但是它导致了 viewDidLoad 的提前调用,因此就出现了文章开头提到的情况,执行顺序变成了 1、3、4、2。


最后我的解决办法是,把成员变量 _viewModel 的初始化放到 viewDidLoad 里。这又是为什么呢?具体内容可以参考这篇文章:iOS 开发中的争议(一)类的成员变量应该如何定义?

大部分的类成员变量都需要在类初使化方法中赋值,大部分的 UIViewController 的成员变量,都需要在 viewDidLoad 方法中赋值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值