weak reference instantiated in another class returns nil in Swift

时间:2019-04-17 01:38:59

标签: swift

I've been experimenting with the VIPER architecture in Swift, and it has exposed a misunderstanding I have with respect to weak references.

The following View Controller has a reference to the presenter (which is instantiated by the wireframe.

If I create the presenter from within the view controller,

class ViewController: UIViewController {
    weak var presenter: Presenter? 

    override func viewDidLoad() {
        super.viewDidLoad()
        let presenterInst = Presenter()
        presenter = presenterInst
        print (presenter)
    }
}

We can print the instance of the presenter - great!

If I use the wireframe class to do the same, the instance is nil:

class Wireframe {
static func createViewModule (view: ViewController) {
        let presenterInst = Presenter()
         view.presenter = presenterInst
}
}


class ViewController: UIViewController {
    weak var presenter: Presenter? 

    override func viewDidLoad() {
        super.viewDidLoad()
        let presenterInst = Presenter()
        presenter = presenterInst
        print (presenter)
    }
}

Which is remedied by making the link to the presenter a strong reference.

So why does instantiating the var from another class mean that the instance becomes nil?

1 个答案:

答案 0 :(得分:2)

It has nothing to do with "another class". An instance not retained by anything else, when assigned to a weak reference, will vanish - sooner or later. It's just that in your first code, it happens later (than when you test it).

In your second code, you test after presenter has become nil, so you actually see it.

In your first code, you don't see it, because it happens right after the print statement:

    let presenterInst = Presenter()
    presenter = presenterInst
    print (presenter) // it still _looks_ okay...
    // but _now_ code ends — and `presenter` is now nil!

To prove this to yourself, allow some time to elapse (using my delay utility):

    let presenterInst = Presenter()
    presenter = presenterInst
    delay(1) {
        print (presenter) // nil
    }