There are times when didReceiveMemoryWarning gets called, but viewDidUnload does not. In my situation I would like to force viewDidUnload when didReceiveMemoryWarning gets called.
I can say this:
[self viewDidUnload];
But will that really unload the views? There is no 开发者_StackOverflow社区self "unloadView".
Why would you want to do this? As long as you remember to call [super didReceiveMemoryWarning]
(assuming you implement the method at all), UIViewController automatically unloads its view if its view has no superview. If this process does not happen, that generally indicates that the view is still part of a view hierarchy and it's not safe to unload.
In the rather unlikely case that you really do need to manually unload a view, you can do so simply by saying self.view = nil
.
In order to test my viewDidUnload code, I did this
-(void)forceUnload {
NSLog(@"forceUnload.enter");
[super didReceiveMemoryWarning];
NSLog(@"forceUnload.leave");
}
I've performed extensive logging and breakpoint setting investigating if didReceiveMemoryWarning
unloads the view when a UIViewController
is not the visibleViewController
. The results: a UIViewController
's view
does not get unloaded (tested using ARC in a UINavigationController
-based project). You need to set self.view
to nil yourself, and it will get reloaded when self.view
is called again. Even logging self.view
will reinitialize it— use isViewLoaded
to test if it's loaded rather than checking the property for nil
.
#define String(fmt,...) [NSString stringWithFormat:fmt,__VA_ARGS__]
#define NSStringFromBOOL(aBool) String(@"%@", aBool?@"YES":@"NO")
- (void)didReceiveMemoryWarning
{
NSLog(@"%s", __FUNCTION__); //-[ViewController didReceiveMemoryWarning]
[super didReceiveMemoryWarning];
if (![self.navigationController.visibleViewController isEqual:self])
{
NSLog(@"%@",NSStringFromBOOL(self.isViewLoaded)); //YES
self.view = nil;
NSLog(@"%@",NSStringFromBOOL(self.isViewLoaded)); //NO
}
}
精彩评论