iOS 6 - viewDidUnload migrate to didReceiveMemoryWarning?
The short answer is that, in many cases, you don't need to change anything. And, you most certainly do not want to simply migrate all of the contents of viewDidUnload
to didReceiveMemoryWarning
.
Generally, most of us do the setting of IBOutlet
references to nil
in viewDidUnload
(largely because Interface Builder would put that there for us) and do the general freeing of memory (e.g. clearing of caches, releasing of easily recreated model data, etc.) in didReceiveMemoryWarning
. If that's the way you do it, then you probably don't require any code changes.
According to the iOS 6 viewDidUnload
documentation:
Views are no longer purged under low-memory conditions and so this method is never called.
Therefore, you do not want to move the setting of your IBOutlet
references to nil
anywhere, because the views are no longer purged. It would make no sense to set them to nil
in didReceiveMemoryWarning
or anything like that.
But, if you were responding to low memory events by releasing easily-recreated model objects, emptying caches, etc., in viewDidUnload
, then that stuff should definitely move to didReceiveMemoryWarning
. But then, again, most of us already had it there already.
Finally, if you free anything in didReceiveMemoryWarning
, just make sure your code doesn't rely upon them being recreated in viewDidLoad
again when you pop back, because that will not be called (since the view, itself, was never unloaded).
As applefreak says, it depends upon what you were doing in viewDidUnload
. If you update your question with explicit examples of what you had in your viewDidUnload
, we can probably provide less abstract counsel.
iOS 6 deprecation of viewWillUnload & move to didReceiveMemoryWarning
According to Apple, they have improved the internal memory management for views enough that the gains achieved by destroying stuff in viewWill/DidUnload
are minimal. Furthermore, they have data suggesting that many apps crash because the apps do not properly handle those notifications, and do "other" stuff not associated with the view unloading.
Finally, a memory warning is now verified as the first and only warning you will get before your app is terminated due to low memory, so it is really the place to handle memory issues.
So, basically, just remove your viewWillUnload
and viewDidUnload
methods. Handle memory issues in didReceiveMemoryWarning
and any other view controller management in the appropriate places.
EDIT
May I ask: what are those "appropiate places"? I used to use
ViewdidUnload in certain situations where view[Will/Did]Disappear were
not entirely adequate. Like going further down on the navigation
controller stack. Would you mind to elaborate further on that? –
Dan1one
That depends. I know that's not what you want to hear, but it's the truth :-)
In general, you should avoid asymmetry. Thus, you should "undo" an operation using the symmetric method from which you "did" the original. In general, you should be able to do all the viewDidUnload
type work in didReceiveMemoryWarning
and dealloc
.
This should really not cause a change, because you had to duplicate most of that code in both of those places anyway.
I don't know what you mean by "going further down on the navigation controller stack" so you will need to clarify that example for me to provide a useful response.
One of the problems with using viewDidDisappear
and viewDidAppear
was that it was hard to know when the view was appearing because it was actually appearing, or because a view that was on top of it was disappearing... causing it to appear.
These pieces of API are supposed to help you address those issues:
- (BOOL)isMovingFromParentViewController
- (BOOL)isMovingToParentViewController
- (BOOL)isBeingDismissed
- (BOOL)isBeingPresented
viewDidUnload and didReceiveMemoryWarning Compatibility
In iOS 6, the viewWillUnload and viewDidUnload methods of UIViewController are now deprecated. If you were using these methods to release data, use the didReceiveMemoryWarning method instead. You can also use this method to release references to the view controller’s view if it is not being used.
The codes currently using in viewDidUnload
should be moved into didReceiveMemoryWarning
. It will work on both iOS5 & iOS6 also. Actually before this change happens the viewDidUnload
method is get invoked only when application did receive memory warning. So viewDidUnload
does not have any particular significance. So they deprecate it.
Deprecation of viewdidUnload in ios 6
It means that if you not using ARC you need to move objects releasing to dealloc
method from viewDidUnload
if you create application only for iOS 6 and higher.
Also look at this answer
viewDidUnload and didReceiveMemoryWarning Compatibility
In iOS 6, the viewWillUnload and viewDidUnload methods of UIViewController are now deprecated. If you were using these methods to release data, use the didReceiveMemoryWarning method instead. You can also use this method to release references to the view controller’s view if it is not being used.
The codes currently using in viewDidUnload
should be moved into didReceiveMemoryWarning
. It will work on both iOS5 & iOS6 also. Actually before this change happens the viewDidUnload
method is get invoked only when application did receive memory warning. So viewDidUnload
does not have any particular significance. So they deprecate it.
iOS6 viewDidUnload Deprecated
You should use the - (void)didReceiveMemoryWarning
and - (void)dealloc
methods.
In iOS 6, the viewWillUnload and viewDidUnload methods of UIViewController are now deprecated. If you were using these methods to release data, use the didReceiveMemoryWarning method instead. You can also use this method to release references to the view controller’s view if it is not being used. You would need to test that the view is not in a window before doing this.
So you should check if your view is in the window first, then remove your observer in the didReceiveMemoryWarning
What works in viewDidUnload should be moved to didReceiveMemoryWarning?
My preferred method is now the following:
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if (self.isViewLoaded && !self.view.window) {
self.view = nil;
}
// Do additional cleanup if necessary
}
Note that the test self.isViewLoaded
is essential, as otherwise accessing the view causes it to load - even the WWDC videos tend to miss that.
If your other references to subviews are weak references, you don't have to nil them out here, otherwise you want to set them to nil, too.
You should get rid of viewDidUnload
completely, and every code there should move to appropriate places. It wasn't guaranteed to be called prior to iOS 6 before anyway.
What works in viewDidUnload should be moved to didReceiveMemoryWarning?
My preferred method is now the following:
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
if (self.isViewLoaded && !self.view.window) {
self.view = nil;
}
// Do additional cleanup if necessary
}
Note that the test self.isViewLoaded
is essential, as otherwise accessing the view causes it to load - even the WWDC videos tend to miss that.
If your other references to subviews are weak references, you don't have to nil them out here, otherwise you want to set them to nil, too.
You should get rid of viewDidUnload
completely, and every code there should move to appropriate places. It wasn't guaranteed to be called prior to iOS 6 before anyway.
NSNotification & didReceiveMemoryWarning in iOS 6
I assume that you added the observer in viewDidLoad
. The problem is that on iOS 6 views are not unloaded, even in a low memory situation. Therefore, if you remove the observer in didReceiveMemoryWarning
, viewDidLoad
will not be called again.
There are two relative simple alternatives that you can choose from:
- Add the observer in
viewWillAppear
and remove it inviewWillDisappear
. - Add the observer in your
initXXX
method and remove it indealloc
.
I is possible to add the observer in viewDidLoad
and remove it in didReceiveMemoryWarning
. But then you have to "manually unload" the view in didReceiveMemoryWarning
, so that viewDidLoad
is later called again. See e.g. https://stackoverflow.com/a/15805715/1187415 for sample code how to forcibly unload the view.
Related Topics
I Get Conflicting Provisioning Settings Error When I Try to Archive to Submit an iOS App
Completion Handler for Uinavigationcontroller "Pushviewcontroller:Animated"
How to Open Maps App Programmatically with Coordinates in Swift
iOS 6 - Viewdidunload Migrate to Didreceivememorywarning
How to Localize the Images in Images.Xcassets
Determine If iOS Device Is 32- or 64-Bit
Uikeyboardframebeginuserinfokey & Uikeyboardframeenduserinfokey
Swiftui: Navigationdestinationlink Deprecated
Images Can't Contain Alpha Channels or Transparencies
Uicollectionview - Horizontal Scroll, Horizontal Layout
How to Remove the Xcode Warning Apple MACh-O Linker Warning 'Pointer Not Aligned at Address
iOS Video Compression Swift iOS 8 Corrupt Video File
Query Available iOS Disk Space with Swift
Swift Numerics and Cgfloat (Cgpoint, Cgrect, etc.)
Enable or Disable iPhone Push Notifications Inside the App
Is There a Swiftui Equivalent for Viewwilldisappear(_:) or Detect When a View Is About to Be Removed