viewDidUnload will not necessarily be called (mainly for handling low memory conditions), and by the time dealloc appears, the view controller is probably no longer in the navigation controller, so self.navigationController will be nil .
I suggest setting the delegate to nil in your implementation of viewWillDisappear: (and setting it to viewWillAppear: instead of viewDidLoad ).
Btw, you see the exact opposite of a memory leak here. A memory leak will be a memory that can no longer be reached and will never be freed. Here you have a memory that has already been freed (your view controller), but still refers to a (dangling) pointer, which causes a crash. An actual leak would usually not directly lead to a failure.
source share