问题
I'm still learning iOS development and have been working with various tutorials and books. Some pre-ARC, some with ARC.
In some cases, we're taught to release all of the properties and subviews of a ViewController on viewDidUnload but in some cases I've been told this is no longer required.
Can someone give a definitive answer? In iOS 5+, does one have to do the whole:
-(void)viewDidUnload
{
[super viewDidUnload];
self.photoViewCell = nil;
self.photoImageView = nil;
self.firstNameTextField = nil;
self.lastNameTextField = nil;
}
... or not? If so, is this only for properties that are descendants of UIView or is it for all properties of the ViewController?
Thanks
回答1:
So each view has a number of owners. When that "owner count" (usually referred to as the retainCount) reaches 0, that object gets destroyed.
In iOS 5, we now have weak references, which essentially means "don't own this object".
Before iOS 5, in our header files, you'd see
IBOutlet UILabel *myLabel;
And this label was added to the XIB file's view. myLabel has 2 owners in this case: it's superview (the view in the XIB file) and the view controller (by having the IBOutlet). When viewDidUnload get's called, the view controller's view has been released, and therefore it's ownership of myLabel is gone. So myLabel at this point only has 1 owner, the view controller. So we needed to release it in viewDidLoad to make sure it didn't have any owners and so was destroyed.
With iOS 5, you will often seen this instead
__weak IBOutlet UILabel *myLabel
This is saying that we don't want the view controller to be an owner of myLabel. So the only owner is the view controller's view. So when viewDidUnload get's called, the view controller's view has already been released, and so its ownership of myLabel has also been released. In this case, myLabel now has no owners and its memory is released. There is no need for the self.myLabel = nil; there.
So with iOS 5, the recommendation is to make all of your IBOutlets a weak reference. With this, you don't even need to implement viewDidUnload, as all the memory has been taken care of for you.
But even if you are using iOS 5, if your IBOutlets aren't weak references, you'll need that code in viewDidUnload.
回答2:
viewDidUnload has nothing to do with retain counting, automatic or otherwise. This method will be called when a view is unloaded due to memory pressure, which means that you should also nil (and release, non-ARC) elements of the view that you hold strong references to. Failure to do this may mean that your app does not free enough memory when under memory pressure, which can lead to it being closed by the OS.
回答3:
You can use viewDidUnload to manage Memory, if your App deserves it.
But don't do a
myInstanceVariable = nil;
You loose your reference to the memory location, where the values of your variable live.
= nil doesn't free the memory. Still, your object has to be deallocated. And therefore the retainCount and retain/release are used.
If you nil your object in viewDidUnload you cannot release in dealloc! Attention!!!
If you know, what you do, you can release and nil your object in viewDidUnload.
ARC:
Using ARC, you must not release manually, even I think you can't do so. ARC takes care of that. Simply use @properties as much as you can with with (weak/strong) attribute to let getters and setters do the work for you. You can declare @properties in your .m file either (like in a class extension).
Simple rule: strong for objects you want to own, weak for objects, you don't want to get lost in a retain cycle and hold ownership to. ARC does the rest in almost all situations. Use weak for delegates for example.
nil objects, where you are sure, you won't send them a message to, otherwise do not.
来源:https://stackoverflow.com/questions/10853479/so-whats-the-deal-with-arc-and-releasing-properties-subviews-on-viewdidunload