Saturday, September 28, 2024
HomeiOS DevelopmentUIKit - loadView vs viewDidLoad

UIKit – loadView vs viewDidLoad

[ad_1]

Weak, unowned or sturdy subviews?


I’ve bought various emails and tweets about this matter, so I made a decision to write down about it, as a result of it’s actually onerous to discover a correct reply for this query on the web. There are some nice posts and programming guides, some some articles are a bit older, nonetheless many individuals are asking the weak vs sturdy IBOutlet query even on the official boards, however noone actually explains the explanations, even on the boards they solely suggest this WWDC session video. So what is going on on right here? 🤔



I did a little analysis on the subject and the very very first thing that we should always state is that this: Apple eliminated the viewDidUnload methodology in iOS6 and from that model the iOS view controller lifecycle modified a bit. If you do not know a lot concerning the lifecycle strategies (demystified), you must learn this text. This was fairly an enormous change and Apple additionally touched their inner view administration. Earlier than iOS6 it was a standard apply to outline weak subviews. As a result of that they had a robust reference to it they usually weren’t releasing it until you eliminated it from the view hierarchy.


This was about 10 years in the past. Now why are we nonetheless afraid of sturdy subviews? The primary motive was the addSubview methodology. The documentation states that it will create a robust reference, which robotically triggered my mind and I outlined my views as weak pointers, since they are going have a robust reference to their mother and father. Appears cheap, proper? 🧠


Weak subviews


Effectively, the issue is that if you wish to outline a weak variable now we have to make use of an non-compulsory, however I do not like the concept of utilizing an non-compulsory variable because the view goes to be all the time there, it is a part of the view hierarchy sooner or later in, it is not going wherever. It is solely going to be “destroyed” when my view controller is deallocated. Ought to I declare it as an implicitly unwrapped non-compulsory?!? Possibly.



import UIKit

class ViewController: UIViewController {

    weak var foo: UILabel! 
    weak var bar: UILabel? 
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()

        
        foo.removeFromSuperview()
        foo.textual content = "crash"
    }
}


Truly you’ll be able to go unsuitable with unwrapped weak pointers, as a result of when you take away your view from the view hiearchy sooner or later in time earlier than the view controller deallocation then your weak pointer might be nil. On this case there will not be any extra sturdy references and your view might be deallocated immediately, so if it is an implicitly unwrapped non-compulsory, then now we have a hassle. Your app will crash when you attempt to entry the property, as a result of it’ll have a nil worth.


So sure you should use implicitly unwrapped non-compulsory variables to retailer subviews, however solely if you’re certain that you’re not going to take away it from the hiearchy. This additionally signifies that you do not belief Apple’s view administration system, which is okay, there might be bugs, however actually that is fairly a vital characteristic and it has been round for a decade by now. 🙃


The opposite different is to make use of an everyday weak non-compulsory variable, however in that case you will all the time need to examine if it is nil or not, which goes to be a ache within the ass, however not less than you are going to be protected for certain. Private opinion: it will not definitely worth the effort in any respect and I by no means saved views like this.



Robust subviews


My advice is to belief Apple and outline your subviews as sturdy properties. Okay, this will also be problematic when you have different sturdy references to the identical stuff, however normally if the view controller has the one reference to that given subview you ought to be completely tremendous.


Since it is a sturdy property you additionally need to initialize the view, however that is not an enormous deal. You possibly can all the time initialize a view with a .zero body and that is it. Alternatively you’ll be able to create a subclass with an everyday init() methodology, that is even higher, becuase you will use auto format for certain and this fashion can set the translatesAutoresizingMaskIntoConstraints property in a single go.


import UIKit

class Label: UILabel {
    
    init() {
        tremendous.init(body: .zero)

        self.translatesAutoresizingMaskIntoConstraints = false
    }
    
    @obtainable(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been carried out")
    }
    
    deinit {
        print("deinit Label")
    }
}

class ViewController: UIViewController {

    
    var foo: Label = .init()
    var bar: UILabel = .init(body: .zero)
    
    override func viewDidLoad() {
        tremendous.viewDidLoad()
        
    }
    
    deinit {
        print("deinit ViewController")
    }
    
}


By implementing a customized deinit methodology and even higher, by making a symbolic breakpoint you’ll be able to simply detect retain cycles and repair reminiscence points. I made some assessments and I can affirm you do not have to be afraid of sturdy views, each the viewcontroller and the view goes to be deallocated if it is wanted. 👻


Unowned subviews


Unowned and weak are roughly equal, I would say that you simply will not must outline views as unowned references, as a result of they are often problematic if it involves initialization. It is normally higher to have a weak reference and examine for nil values, however after all there might be some instances the place you would possibly want an unowned subview reference.


Utilizing loadView and viewDidLoad



The loadView methodology can be utilized to create your individual views manually. It is best to by no means name this methodology straight, nevertheless it’s save to override it. The opposite factor that you shouldn’t is that if you’re utilizing this methodology to override the basis view, then you definately should not name tremendous.loadView().



import UIKit

class ViewController: UIViewController {
    
    override func loadView() {
        view = UIView(body: .zero)

        
            
    }
}


In each different case whenever you simply wish to add views to the view hierarchy, it is fully tremendous to name the tremendous methodology. I am normally implementing this methodology to setup views and constraints.


import UIKit 

class ViewController: UIViewController {

    var foo: Label = .init()
    
    override func loadView() {
        tremendous.loadView()
        
        view.addSubview(foo)
        
        NSLayoutConstraint.activate([
            view.centerXAnchor.constraint(equalTo: foo.centerXAnchor),
            view.leadingAnchor.constraint(equalTo: foo.leadingAnchor),
            view.trailingAnchor.constraint(equalTo: foo.trailingAnchor),
            foo.heightAnchor.constraint(equalToConstant: 44),
        ])
    }
}


This manner I can make certain that each single view is prepared by the point the viewDidLoad methodology is named. It’s attainable to configure views contained in the loadView methodology too, however I choose to maintain the hierarchy setup there and I place every little thing else contained in the viewDidLoad perform. I imply controller associated stuff solely, like organising navigation bar buttons and issues like this.


As I discussed this in my earlier article, I choose to make use of subclasses to configure my views, I additionally transfer format constraints there (as a perform that returns them based mostly on some parameters) to maintain the view controller clear. Contained in the viewDidLoad methodology I can carry out further person interface associated actions, however that is it I do not use it for including or styling views anymore.


[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments