viewDidLoad 中的代码每次调用时都会运行

Posted

技术标签:

【中文标题】viewDidLoad 中的代码每次调用时都会运行【英文标题】:Code in viewDidLoad runs every time it is called 【发布时间】:2014-11-05 14:49:07 【问题描述】:

大家好,我在 Udemy 上一门课程,代码要求在 viewDidLoad 函数中放置代码,如下所示:

    override func viewDidLoad() 
    super.viewDidLoad()

    placesArray.append(["name":"Taj Mahal", "lat":"27.175607", "lon":"78.042112"])


数组追加应该只运行一次,但是,当我转到另一个视图控制器并返回时,它会运行代码再次追加。所以我现在有一个有 2 行的数组,它们都是泰姬陵。

我以为viewDidLoad函数只运行一次代码?

有没有办法解决这个问题?

谢谢。

附录: 我使用的是 Swift,所以在创建和启动 viewController 时看不到任何 alloc 和 init。听起来很奇怪,视频教程让它在 viewDidLoad 中工作,并且培训师正在使用情节提要从初始表视图控制器到视图控制器上的地图视图,并且在地图视图上只有一个后退按钮也可以通过情节提要返回表格视图控制器。 - 可能是因为我有最新版本的 Swift 语言,而培训师使用的是早期版本,(因为我注意到之前的编码有些细微差别)但你永远不知道。无论哪种方式,只要他触摸后退按钮,它就不再运行附加代码。 我正在尝试与培训师联系,因为这里有一些建议,尽管它们很好,但似乎不起作用。 与培训师联系后,我会将解决方案放在这里。

【问题讨论】:

也许当你切换到另一个视图控制器时,旧的视图控制器是 dealloc,当你回来时它又加载了?! 你可能会带着一个不放松的转场回来。你不应该那样做。它创建了一个新实例,实际上并没有返回。 【参考方案1】:

当您的视图控制器的view 完成加载时,将调用viewDidLoad 方法。 view 将在视图控制器的 view 属性为 nil 并且尝试访问它时加载。

UIViewController *myVC = [[UIViewController alloc] init];
UIView *aView = myVC.view; // this loads myVC's view; viewDidLoad is called when it completes loading.

如果view 已卸载(通常由于内存限制),它将在下次访问view 属性时调用。

数据集的操作通常不应在视图方法中完成。考虑将其移至视图控制器的init(或不同的“数据源”类)。

【讨论】:

更具体地说。每当调用视图控制器视图的框架时,都会调用 viewDidLoad。因此,例如,如果您将其帧大小设置为容器的大小,则 viewDidLoad 将被命中。但是 viewWillAppear 和 viewDidAppear 直到 addSubview (或变体)之后才会被击中 @GnarlyDog:不,这是不真实的。如果您的view 属性已设置,则调用self.view.frame = someFrame 不会导致viewDidLoad。例如,self.view.frame 是在您旋转屏幕时设置的,但您不会在每次旋转时收到 viewDidLoad 调用,除非您已对 view 进行了核对。 抱歉,回复含糊。我的意思是在你分配初始化之后,而不是每次设置框架时。我只是在另一个内部分配了一个 ViewController,但没有呈现它或将它的子视图添加到视图中。未调用 viewDidLoad。但是,如果我设置 view.frame = my.view.frame 则调用 viewDidLoad。但是 viewWillAppear 不是。本质上,viewDidLoad(和 loadView)似乎被懒惰地调用了。 是的。 self.view 的加入是导致viewDidLoad 的原因,而不是.frame。为清楚起见,我更新了示例。 视图不再被卸载,内存压力与否。 viewDidLoad 将在任何视图控制器的生命周期中被调用一次,除非您作为开发人员将视图归零,这是一个坏主意【参考方案2】:

我想您正在尝试在 viewDidLoad 中进行数据初始化。如果在viewDidLoad之前没有对placesArray进行其他操作,那么不用append,直接设置placesArray怎么样:

placesArray = ["name":"Taj Mahal", "lat":"27.175607", "lon":"78.042112"]

那么即使您的视图由于某些原因被卸载。泰姬陵仍将仅添加一次。

【讨论】:

【参考方案3】:

viewDidLoad 在视图控制器的视图属性设置时被调用。这什么时候发生?这取决于视图控制器的包含方式:

UINavigationController - 视图控制器视图在添加到导航堆栈时被加载,并在它们被删除时“卸载”(尽管viewDidUnload 方法已被弃用)。

UITabBarController - 视图控制器视图在添加到选项卡栏时加载,无论它们是否在屏幕上。当您从一个选项卡切换到另一个选项卡时,它们会保持加载状态。

根据您的需求和用例,您可以创建自己的视图控制器容器来满足您的需求。以正确的方式查看 Apple 文档: https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/CreatingCustomContainerViewControllers/CreatingCustomContainerViewControllers.html

【讨论】:

以上是关于viewDidLoad 中的代码每次调用时都会运行的主要内容,如果未能解决你的问题,请参考以下文章

Angular Service 在每次调用时都会重置

每次渲染正文时都会调用 SwiftUI Picker onReceive()

Angular2,为啥每次移动鼠标时都会调用函数

Bash:每次运行该脚本时都会从脚本中增加一个变量

每次Navigator.push到下一页时都会调用的回调

为啥 Django makemigrations 每次运行时都会检测到由于 help_text/verbose_name 属性中的重音而导致的更改?