self refrence inside swift closure return nil some

2019-04-16 16:11发布

问题:

I am accessing instance method inside closure in swift, self reference become nil in some cases which result crash my program. I tried to access using [weak self] but it failed to call the instance method when self is nil.

[weak self] () -> () in

回答1:

The whole point of [weak self] is to not create a reference to self (probably to avoid circular links and memory leaks) so that it can be released. If that happens, then self will be nil.

You should either not use [weak self] or, better yet probably, be prepared to handle the case of self having been released and set to nil.

guard let strong = self else { return }

Take the example:

import UIKit
import PlaygroundSupport

class Foo {
    let name : String

    init(name:String) {
        self.name = name

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
            print(self!.name)
        }
    }
}

Foo(name:"freddie")

PlaygroundPage.current.needsIndefiniteExecution = true

In this case, you'll get a crash, because self is released before the async callback is made.

You can either change the asyncAfter call to be:

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
            print(self.name)
        }

will guarantee that self isn't released until after the callback is made.

Or you can use something like:

        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) { [weak self] in
            guard let strong = self else { print("self released") ; return }
            print(strong.name)
        }


回答2:

I am able to fix this issue by making strong instance while creating it, in my case this weak variable was making nil to self. Thanks all for providing suggestion for my queries.