Does defining functions inside viewdidload () save more memory and define them outside?

Since viewdidload () is called only once in the lifecycle of that UIViewController object instance, does that mean the example below is "bad practice" since setBackgroundColor (), a function that is called only once, is awkwardly loaded into the memory of the entire class when should it really exist completely (defined and called) inside viewdidload ()? Or from an efficiency standpoint, it doesn't matter where setBackgroundColor () is defined and called?

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

}

      

+3


source to share


4 answers


This is not a case of using memory, it is a matter of loading the image efficiently.

UIViewControllers controls views. But views are not created at the same time as the view controller.

Setting the background color of, indeed, any view configuration, is viewDidLoad

done because when this method is called, the view has been created (although not necessarily displayed) at a convenient point in the view controller's lifecycle.If you created a view controller and then called your method setBackgroundColor

. part of the self.view

call will cause the view to be created immediately if it hasn't already been created.



For certain methods, such as the view manager views, this allows the authoring methods to return as quickly as possible without the view being loaded directly, and keep the UI responsive.

It is because of this lazy loading of views that the UIViewController has a parameter isViewLoaded

that returns a Bool for whether the view is loaded into memory or not, but does not cause the view to load.

+2


source


Creating a local function for a method changes its scope, but not the lifetime of the code compiled from it. The same goes for class methods: their binaries are not individually controlled, at least not at this time. However, this is not very important since the executable code of your function is relatively tiny.

It is important here that the function name is not visible in the outer scope, allowing other methods to define their own functions setBackgroundColor()

, not related to what is defined in viewDidLoad

:

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

      



This improves readability because the function definition is where it is used. It also improves maintainability because whoever is refactoring your code can rest assured that there can be no other use setBackgroundColor

outside viewDidLoad

.

Of course, this is just an example. The nested function is not needed here - you can rewrite it without the function setBackgroundColor

, for example:

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

      

+3


source


I don't see anything in your code that requires attention to memory. Micro-optimization is the longest time in software development. But as you asked, viewDidLoad

is only called once. From Apple Working with View Controllers :

viewDidLoad()

-Called when the content view of the view controller (the top of its view hierarchy) is created and loaded from the storyboard. It seems that the viewpoint controllers will be assigned valid values ​​by the time this method is called. Use this method to perform any additional configuration required by your controller.

Typically, iOS calls viewDidLoad()

only once when its content view is first created; however, the content view is not necessarily created when the controller is first instantiated. Instead, it is generated lazily when the system or any code accesses the view properties of the controllers.

+2


source


My guess is that any loss in efficiency is worth it to get more readable code. In fact, compiler optimizations can even inline a function if you mark it as private

. I don't know enough about the Swift Compiler (LLVM) to know if this is true, but it might.

Martin Fowler has a great article on function length in which he claims that he has many functions that are one line long simply because they make the code easier to understand.

Some people are concerned about short functions because they are concerned about the cost of executing a function call. When I was young it was from time to time, but it is very rare. Compiler optimizations often work better with shorter functions that are easier to cache. As always, general guidelines for performance optimization are what counts.

Not sure if his notes on function caching apply to Swift, but he also says:

If you need to put in the effort of looking at a piece of code to figure out what it does, then you should extract it into a function and name the function after that "what". This way, when you read it again, the purpose of the function jumps right at you

In general, I wouldn't put too much emphasis on optimization unless you notice that this is a problem. YAGNI

... And as stated in Code Different, yes it ViewDidLoad()

is called only once.

+2


source







All Articles