deinit() ceases to call when this code line of code executes

34 views Asked by At

Recently I have been reviewing my code and noticed in one of my view controllers, deinit() is not called.

After commenting out this line, deinit calls successfully:

  NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil)
        { notification in self.keyboardWillShow(notification: notification) }

I'm aware of the fact you need to remove the observer, but if I replace

self.keyboardWillShow(notification: notification)

with

print("hello world")

deinit() calls successfully.

The code inside of my local function "keyboardWillShow" is call commented out, however the function signature is

func keyboardWillShow(notification: Notification)

Any recommendations on how I can improve this code to not retain references and properly hit deinit()/

Thank you!!

1

There are 1 answers

0
Paulw11 On BEST ANSWER

Your closure is capturing a strong reference to self, which prevents your object from being released; you have a retain cycle. When you don't reference self in the closure you avoid this cycle, which is why your view controller is released when you have just the print statement.

You can use [weak self] in the closure to prevent this; you then need to unwrap self in the closure before you use it.

NotificationCenter.default.addObserver(forName: .UIKeyboardWillShow, object: nil, queue: nil) 
{ [weak self] notification in 
    self?.keyboardWillShow(notification: notification)
}