简体   繁体   中英

Why are the outlets by default declared as weak?

I looked up this topic on google but have not got an understandable answer yet, the problem is that I know that when two classes are coupled together by instantiating an object in the first class from the second class and declaring another object in the second class from the first class this will cause a retain cycle that should be broken by using the keyword weak or unowned , yet I can not apply this way of thinking on the IBOutlets being declared as weak for example

class SignUpViewController: UIViewController {
 override func viewDidLoad() {
        super.viewDidLoad()
    }
@IBOutlet weak var signUpBttn: UIButton!
}

this is an outlet in my viewController class, why the outlet is declared as weak ? as per what I understand is that to have a retain cycle, the uibutton class should have an object from the viewController class so that the two classes (viewController and uibutton) become coupled together can anybody clarify what is happening under the hood?

all ui element in a view controller are part of the viewController view. so view is a UIView class and outlets are reference in the viewController to UIView class elements, so if the view is removed form the view hierarchy all cross element should be weak to avoid cross reference. thew eid problem about this is the reference from apple MVC, where a ViewController is a Controller but have a bunch o related code of the view part. all you outlets should be placed in the UIView class of you ViewController.

TLDR - in my opinion it's not a good decision.

A strong reference denotes ownership. The view or view controller is the owner of the views therefore the logical choice should be strong .

However, in most situations this does not really matter because the views are also strongly referenced by their parent in the view hierarchy.

When does it matter? It matters in situations when you are dynamically updating the view hierarchy by removing views/constraints etc. Once you remove a view/constraint from the hierarchy and you don't have a strong reference to it, it will get removed from memory.

Also note that the combination of weak and ! is a bit dangerous because ! denotes a reference that you expect never to be nil .

This can lead to errors, for example:

@IBOutlet weak var constraint: NSLayoutConstraint!

...

constraint.isActive = false // removes constraint from hierarchy, assigns `nil` to constraint
...
constraint.isActive = true // crashes the app

Personally, I always make outlets strong . For any weak references I always use ? and not ! .

Note that weak in this case doesn't have anything to do with protection against reference cycles. It was just a personal decision by Xcode developers.

Historically, there might be a connection with UIViewController.viewDidUnload . However, that method is never called since iOS 6.

Apple recommends that an @IBOutlet be declared as strong . Many discussions / articles can be found about this.

If you take a look at this video from Apple's 2015 WWDC , right around the 32:30 mark: https://developer.apple.com/videos/play/wwdc2015/407/

He states:

In general you should make your outlet strong, especially if you are connecting an outlet to a sub view or to a constraint that's not always going to be retained by the view hierarchy. The only time you really need to make an outlet weak is if you have a custom view that references something back up the view hierarchy and in general that's not recommended.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM