Swift 在viewdidload()内部定义函数比在外部定义函数节省更多内存吗?

Swift 在viewdidload()内部定义函数比在外部定义函数节省更多内存吗?,swift,uikit,viewdidload,Swift,Uikit,Viewdidload,由于viewdidload()在UIViewController对象实例的生命周期中只被调用一次,这是否意味着下面的示例是一个“糟糕的做法”,因为setBackgroundColor()是一个只被调用一次的函数,它不必要地被加载到整个类的内存中,而实际上它应该完全存在(定义并调用)在viewdidload()内部?或者从效率的角度来看,在哪里定义和调用setBackgroundColor()并不重要吗 class MasterViewController: UIViewController {

由于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()
    }

}

我看不出你的代码中有任何值得考虑的内存问题。微优化是软件开发中最大的时间浪费。但自从你问起,
viewDidLoad
只被调用一次。来自苹果:

viewDidLoad()
-在从情节提要创建和加载视图控制器的内容视图(其视图层次结构的顶部)时调用。在调用此方法时,确保视图控制器的输出具有有效值。使用此方法可执行视图控制器所需的任何其他设置

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


使函数成为方法的局部函数会改变其作用域,但不会改变从该函数编译的代码的生存期。类的方法也是如此:它们的二进制代码不是单独管理的,至少现在不是。不过这不是什么大问题,因为函数的可执行代码相对较小

这里重要的是函数名在其外部作用域中不可见,让其他方法定义自己的
setBackgroundColor()
函数,这些函数与
viewdiload
中定义的函数无关:

override func viewDidLoad() {
    super.viewDidLoad()
    // Nested function definition
    func setBackgroundColor() {
        self.view.backgroundColor = UIColor.green
    }
    // Calling nested function
    setBackgroundColor()
}
这提高了可读性,因为函数定义就在使用它的地方。它还提高了可维护性,因为重构代码的人都可以确定在
viewDidLoad
之外不能再使用
setBackgroundColor

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

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

这不是内存使用的问题,而是有效加载视图的问题

UIViewController控制视图。但视图不是与视图控制器同时创建的

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

对于某些方法,例如视图控制器演示,这允许创建方法在不立即加载视图的情况下尽快返回,并保持UI响应


正是由于视图的这种延迟加载,UIViewController才有了
isViewLoaded
参数,该参数返回一个Bool,用于判断视图是否加载到内存中,但不会导致视图加载。

我的猜测是,效率上的任何损失都值得拥有可读性更强的代码。事实上,编译器优化如果您将函数标记为
private
,甚至可能会内联该函数。我对Swift编译器(LLVM)了解不够,不知道这是否确实是真的,但它可能是真的

Martin Fowler在一篇文章中指出,他拥有许多一行长的函数,因为它们使代码更容易理解

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

不确定他关于函数缓存的说明是否适用于Swift,但他还表示:

如果你必须花精力去看一段代码来弄清楚它在做什么,那么你应该把它提取到一个函数中,然后用“what”来命名这个函数。这样,当你再次阅读它时,函数的用途就在你眼前了

一般来说,我不会太关注优化,除非你注意到这是一个问题


…正如代码所指出的,yesViewDidLoad()只调用一次。

文档中说“使用此方法执行视图控制器所需的任何附加设置”,但设置背景色真的是“附加设置”吗?它不是主要的基础设置吗?func不在viewdidload()内时不会加载,这使我相信“附加设置”的措辞有点误导。是吗?重要的是要认识到viewController与视图不同。您正在设置视图的颜色,这是viewController设置的一部分。