iOS 6 - Viewdidunload Migrate to Didreceivememorywarning

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 in viewWillDisappear.
  • Add the observer in your initXXX method and remove it in dealloc.

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



Leave a reply



Submit