2
votes

This is not pure curiosity, there is a feeling that I may misunderstand something about weak references in Swift.

Suppose I create a class from a View Controller and pass its reference to the initialiser:

class = MyClass(vc: self)

Since the storyboard and window already keep a reference to this View Controller, it seems logical for MyClass to have a weak reference to it (for the similar reason all references created within IB are weak by default):

class MyClass: NSObject {
    private weak var viewController: UIViewController

    init(vc: UIViewController) {
       self.viewController = vc
       super.init
    }

    func setViewController(_ vc: UIViewController) {
       self.viewController = vc
    }

    ...
}

However this code gives compilation error, as viewController variable isn't optional. So I had to add '!' to viewController declaration and remove the initialiser, leaving only setViewController which looks rather unnatural.

What is the reason behind disallowing non-optional weak data?

1
1) "Since the storyboard and window already keep a reference to this View Controller, it seems logical for MyClass to have a weak reference to it" Nope, this is not a good reason. You should use a weak reference if your object doesn't have an owning relationship over the vc, in order to block retain cycles. 2) "for the similar reason all references created within IB are weak by default" simply using a strong reference is preferred these days. 3) What would you expect to happen when you reference viewController, when the strong references to it expire?Alexander
Alexander: 1) 'You should use a weak reference if your object doesn't have an owning relationship over the vc'. Indeed, MyClass doesn't own the VC; it's the storyboard who owns it. Therefore weak reference should be rightcyanide
Alexander: 2) If strong reference is preferred, why IB takes weak references by default? Pure nostalgia to old days? :) As you've mentioned, weak references help to block retained cycles. Modern Java doesn't use reference counts, so it doesn't offer weak references. On the contrary, Swift uses reference counts, so weak references are needed sometimes.cyanide
Alexander 3) Can you please explain the meaning of 'strong reference is to expire'?cyanide
1) By your reasoning, only 1 strong reference should ever exist to an object. That's simply not the case. If you need a guaranteed life time of an object, you use a strong reference.Alexander

1 Answers

7
votes

The very definition of a weak variable is that the variable does not increase the reference count of the object and, more importantly for your question, the variable's value will automatically be set to nil when the referenced object gets deallocated.

Since the variable must allow for a nil value, it must be optional. This is why non-optional weak variables are disallowed.

Do not declare viewController to be implicitly unwrapped (using !). Make it a proper optional (using ?).