Objective-C Accessor Methods and Use of Autorelease
I've been reading an apple document on Memory Management and am now a bit confused regarding the recommended implementation of Accessors. Apple cites 3 approaches in implementing accessors.
Technique 1
I've copied the code from the first technique which reflects: "Getter retains and autoreleases the value before returning it; setter releases the old value and retains (or copies) the new value." This first technique is stated to be more robust but suffers performance penalties on frequently called getters.
- (NSString*) title {
return [[title retain] autorelease];
}
- (void) setTitle: (NSString*) newTitle {
if (title != newTitle) {
[title release];
title = [newTitle retain]; // Or copy, depending on you开发者_如何学Pythonr needs.
}
}
skipping Technique 2
Technique 3
The third technique is better for frequently called setters and getters. This is also the method I've always followed.
- (NSString*) title {
return title;
}
- (void) setTitle: (NSString*) newTitle {
if (newTitle != title) {
[title release];
title = [newTitle retain]; // Or copy, depending on your needs.
}
}
My questions are:
(Technique 1) The setter first releases the existing value even if it doesn't point to anything. This would send a message to nil which I understand is supported in Objective-C but still looks odd. Am I understanding this correctly?
(Technique 1) Why is the retain stacked inside an autorelease?
(Technique 1) Is the caller whom uses the getter expected to call release after they're done with the object?
The apple developer documentation page can be found at: Memory Management Programming Guide - Accessor Methods
(Technique 1) The setter first releases the existing value even if it doesn't point to anything. This would send a message to nil which I understand is supported in Objective-C but still looks odd. Am I understanding this correctly?
Yup. Messages to nil
matter not.
(Technique 1) Why is the retain stacked inside an autorelease?
That guarantees that the following doesn't break:
x = [foo title];
[foo setTitle: @"bar"];
[x length]; // x has been released, possibly, if -title didn't retain/autorelease
(Technique 1) Is the caller whom uses the getter expected to call release after they're done with the object?
No.
Sending a message to nil is defined to do nothing. This setter is an excellent example of how that allows you to write simpler code:
[title release]
instead ofif (title != nil) [title release];
. Note also that no special checks for nil are necessary onnewTitle
.The retain/autorelease pair in the getter mean that the returned object will remain valid through the lifetime of the current function call (technically, until the autorelease pool is drained), even if the setter is called. The documentation you cite gives an example of how that can be helpful if there's a variable with a "non-owning reference" to the value.
NO. The value has already been autoreleased; caller must not release it again.
精彩评论