在viewdidload()中定义函数是否比在外部定义更节省内存?

时间:2017-08-07 15:19:09

标签: swift uikit viewdidload

由于viewdidload()仅在UIViewController对象的该实例的生命周期中被调用一次,这是否意味着下面的这个例子是一个"不好的做法"既然setBackgroundColor(),一个只调用一次的函数,当它真的应该只在viewdidload()里面完全存在(定义和调用)时,不必要地加载到整个类的内存中?或者就效率而言,定义和调用setBackgroundColor()的位置无关紧要?

class MasterViewController: UIViewController {

    func setBackgroundColor() {
        self.view.backgroundColor = UIColor.green
    }

    // Do any additional setup after loading the view, typically from a nib.
    override func viewDidLoad() {
        super.viewDidLoad()

        setBackgroundColor()

    }

    // Dispose of any resources that can be recreated.
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

}

4 个答案:

答案 0 :(得分:3)

使方法的本地函数改变其范围,但不改变从其编译的代码的生命周期。对于类的方法也是如此:它们的二进制代码不是单独管理的,至少目前不是。但这并不是什么大问题,因为你的函数的可执行代码相对较小。

这里重要的是函数名称在其外部范围内不可见,让其他方法定义自己的setBackgroundColor()函数与viewDidLoad中定义的函数无关:

override func viewDidLoad() {
    super.viewDidLoad()
    // Nested function definition
    func setBackgroundColor() {
        self.view.backgroundColor = UIColor.green
    }
    // Calling nested function
    setBackgroundColor()
}

这提高了可读性,因为函数定义就在那里使用它。它还提高了可维护性,因为无论谁重构您的代码,都可以确定setBackgroundColor之外的viewDidLoad没有其他用途。

当然,这只是一个例子。这里不需要嵌套函数 - 您可以在没有setBackgroundColor函数的情况下重写它,如下所示:

override func viewDidLoad() {
    super.viewDidLoad()
    self.view.backgroundColor = UIColor.green
}

答案 1 :(得分:2)

我的代码中没有任何内容可以保证内存问题。微优化是软件开发中最大的浪费时间。但是既然你问过,viewDidLoad只被调用一次。来自Apple的Work with View Controllers

  

viewDidLoad() - 在视图控制器的内容视图(其视图层次结构的顶部)创建并从故事板加载时调用。在调用此方法时,视图控制器的出口保证具有有效值。使用此方法执行视图控制器所需的任何其他设置。

     

通常情况下,iOS首次创建内容视图时只调用viewDidLoad()一次;但是,在首次实例化控制器时,不一定要创建内容视图。相反,它是在系统或任何代码第一次访问控制器的视图属性时延迟创建的。

答案 2 :(得分:2)

不是内存使用情况,而是有效加载视图。

UIViewControllers控制视图。但视图不会与视图控制器同时创建。

viewDidLoad中设置背景颜色,实际上是任何类型的视图配置都已完成,因为在调用该方法时,视图已在视图控制器中的方便点创建(尽管未必显示) #39;生命周期。如果您创建了视图控制器,然后调用了setBackgroundColor方法,则调用的self.view部分会导致视图立即创建(如果尚未创建)。

对于某些方法,例如视图控制器演示,这允许创建方法尽可能快地返回,而不会立即加载视图并保持UI响应。

由于这种延迟的视图加载,UIViewController具有isViewLoaded参数,该参数返回Bool以确定视图是否加载到内存中,但不会导致视图加载。

答案 3 :(得分:2)

我的猜测是,任何效率损失都值得拥有更多可读代码。实际上,如果将标记为private,编译器优化甚至可以内联函数。我不太了解Swift编译器(LLVM)知道这是否确实如此,但可能是。

Martin Fowler有一个great article on function length,他说他有很多一行的函数,因为它们使代码更容易理解。

  

有些人担心功能短缺,因为他们担心功能调用的性能成本。当我年轻的时候,这偶尔会成为一个因素,但现在这种情况非常罕见。优化编译器通常可以更好地使用可以更容易缓存的较短函数。与以往一样,关于性能优化的一般指导原则是重要的。

不确定他关于功能缓存的说明是否适用于Swift,但他也说:

  

如果你不得不花费精力去查看代码片段以找出它正在做什么,那么你应该将它提取到一个函数中并在“what”之后命名该函数。这样当你再次阅读时,该功能的目的就在你身边跳跃

一般情况下,除非您注意到这是一个问题,否则我不会过分关注优化。 YAGNI

......正如Code Different所指出的那样,是ViewDidLoad()只被调用一次。