Explanation of `self` usage during dealloc?
I'm trying to lock down my understanding of proper memory management within Objective-C.
I've gotten into the habit of explicitly declaring self.myProperty
rather than just myProperty
because I was encountering occasional scenarios where a property would not be set to the reference that I intended.
Now, I'm reading Apple documentation on releasing IBOutlets
, and they say that all outlets should be set to nil
during dealloc
. So, I put this in place as follows and experienced crashes as a result:
- (void)dealloc {
[self.dataModel close];
[self.dataModel release], self.dataModel = nil;
[super dealloc];
}
So, I tried taking out the "self" references, like so:
- (void)dealloc {
[dataModel close];
[dataModel release], dataModel = nil;
[super dealloc];
}
This second system seems to work as expected. However, it has me a bit confused. Why would self
cause a c开发者_开发百科rash in that case, when I thought self
was a fairly benign reference more used as a formality than anything else? Also, if self
is not appropriate in this case, then I have to ask: when should you include self
references, and when should you not?
I have adopted the following after seeing Apple sample code and iphone dev books.
set outlets to nil in 'viewDidUnload' (use SELF accessor) release them in 'dealloc' (no SELF)
- (void)viewDidUnload {
// Relinquish ownership of anything that can be recreated in viewDidLoad or on demand.
// For example: self.myOutlet = nil;
self.button = nil
}
- (void)dealloc {
// no SELF
[button release]; // UI objects
[images release]; // model objects
}
[self.dataModel release]
will release a reference to dataModel
that you don't own. The subsequent self.dataModel = nil
is equivalent to calling [self setDataModel:nil]
, and the setter method will itself release the dataModel
, which you've already done.
Simplest thing would be to only do self.dataModel = nil
.
As a more general point, self.blah
is not just a polite way of accessing a field. It invokes a method, and that may have side effects. The purpose of such side effects should be to make life safer and easier. If you forget that the method is being called, though, then it can lead to confusion, as here.
As a rule, you should structure your property methods to encapsulate tricky stuff like memory management -- the default implementations will do this as long as you've declared the property attributes correctly -- and then leave it to them. Mixing and matching your own memory management and your property methods' memory management will almost always trip you up in the end.
精彩评论