芮星晨 芮星晨 - 7 months ago 28
Swift Question

ios: why it call deinit immediately

today I faced a problem , the vc never call deinit, so I added a weak

func showAddCityViewController() {
weak var vc:SWAddCityViewController!
vc = SWAddCityViewController()
vc.delegate = self
let nav = UINavigationController(rootViewController: vc)
dispatch_async(dispatch_get_main_queue(), {
self.presentVC(nav)
})
}


I run this function and then get a


fatal error: unexpectedly found nil while unwrapping an Optional value


the vc just go to nil ,but I don't know why , what should I do to make this code happy?

Answer

You wrote this:

    weak var vc:SWAddCityViewController!
    vc =  SWAddCityViewController()

The vc variable is an “implicitly unwrapped Optional”, which means it can either point to an existing (not-deallocated) object, or it can be nil.

You create a new SWAddCityViewController object and assign it to vc. After the assignment statement completes, there is exactly one weak reference to the new object (in vc) and there are no strong references to it. An object is deallocated as soon as it has no strong references, so it is deallocated as soon as the assignment statement completes.

Since vc was a weak reference to the object, part of deallocating the object sets vc to nil. When you try to set vc.delegate on the next line, Swift generates code to unwrap vc automatically (since you declared it with !). Since vc is nil, you get a fatal error. You cannot unwrap an optional that's set to nil because it's not wrapping anything.

I don't see any reason to declare vc weak in that function. Just get rid of the weak attribute.

Your other complaint is that (with weak) the object doesn't get deallocated later. You have a “retain cycle”. Did you declare the delegate property of SWAddCityViewController using weak? You usually want to declare delegate properties weak.

If that doesn't fix the problem, you need to look for other places where you have a retain cycle involving the object.

Comments