When should I release objects in -voidviewDidUnload rather than in -dealloc?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
This question matters mostly in legacy Objective-C code, because viewDidUnload belonged to an older memory-management model on iOS. The short answer is that temporary view-related objects used to be released in viewDidUnload, while objects owned for the lifetime of the controller belonged in dealloc, but modern iOS code should not use viewDidUnload at all.
What viewDidUnload Was For
Before iOS 6, UIKit could unload a view controller's view hierarchy after a memory warning if the view was off-screen. When that happened, viewDidUnload gave you a chance to clear references to subviews and other resources that could be recreated the next time viewDidLoad ran.
Typical examples were:
- '
IBOutletreferences to labels, buttons, and image views' - Cached images tied directly to the unloaded view
- Temporary layout state that only mattered while the view existed
A pre-ARC controller often looked like this:
The important idea is that these objects were not being destroyed because the controller itself was dying. They were being released because the view tree had gone away and could later be rebuilt.
What dealloc Is For
dealloc is different. It runs when the controller object itself is about to be destroyed. Anything the controller owns for its full lifetime belongs there in manual reference-counted code.
That includes:
- Model objects retained by the controller
- Notification observers or KVO registrations
- Timers, file handles, or other non-view resources
- Any remaining retained properties that were not already cleared earlier
A legacy non-ARC example:
Even if you set some properties to nil in viewDidUnload, you still had to make sure final cleanup happened in dealloc. viewDidUnload was optional and conditional. dealloc was final.
How to Decide What Went Where
The old rule of thumb was:
- If the object should survive as long as the controller survives, clean it up in
dealloc. - If the object exists only to support the current view hierarchy and can be recreated later, it may be cleared in
viewDidUnload.
For example, a table view outlet belonged in viewDidUnload because the table view itself was part of the unloadable view tree. A data array fetched from the network usually did not, because you often wanted the controller to keep that data even if the view disappeared temporarily.
That distinction matters because clearing too much in viewDidUnload caused unnecessary reloading, while clearing too little wasted memory.
Modern iOS Guidance
viewDidUnload was deprecated in iOS 6 and is gone from modern UIKit practice. Views are no longer unloaded that way, so current code should not implement it.
Under ARC, you also do not manually release Objective-C objects. Modern equivalents are:
- Use strong and weak properties correctly
- Clear observers, delegates, or callbacks when needed
- Put final non-memory cleanup in
dealloconly when ARC does not handle it automatically
A modern controller might only use dealloc for observer cleanup:
If you are maintaining legacy code, the key question is whether that code still targets an era where viewDidUnload could actually be called. In almost all current projects, the answer is no.
Common Pitfalls
- Treating
viewDidUnloadas if it were a general-purpose cleanup method is wrong in modern iOS because the method is obsolete. - Releasing model objects in
viewDidUnloadcan force unnecessary reloads when only the view hierarchy needed to be rebuilt. - Forgetting that
deallocstill had to handle final cleanup caused leaks or dangling observers in manual memory-management code. - Mixing ARC assumptions with pre-ARC code leads to broken cleanup logic. The two models should be reasoned about separately.
Summary
- In legacy UIKit,
viewDidUnloadwas for releasable view-related objects that could be recreated later. - '
deallochandled final cleanup for the controller's full lifetime.' - '
viewDidUnloadwas conditional;deallocwas final.' - In modern iOS,
viewDidUnloadis obsolete, and ARC removes most manual release work.

