Properties, Attributes and Retain+Autorelease
Properties, Attributes and Retain+Autorelease
- Subject: Properties, Attributes and Retain+Autorelease
- From: Markus Hanauska <email@hidden>
- Date: Wed, 29 Jun 2011 12:53:26 +0200
Unfortunately the documentation on properties is really inadequate since Apple fails to provide "pseudo-code" for every possible attribute combination. E.g. the nonatomic attribute has a couple of dangerous side effects that seem to be unknown even to developers using properties for years. The documentation should provide sample code for the following attribute combinations:
a) retain
b) retain, nonatomic
c) copy
d) copy, nonatomic
e) assign
f) assign, nonatomic
Let me show you which dangerous side effects I'm talking about by providing sample code for the cases a) and b) as I would have implemented them:
a) retain
- (id)value
{
id res;
[_magic_lock lock];
res = [value retain];
[_magic_lock unlock];
return [res autorelease];
}
- (void)setValue:(id)aNewValue
{
[_magic_lock lock];
if (aNewValue != value) {
[value release];
value = [aNewValue retain];
}
[_magic_lock unlock];
}
b) retain, nonatomic
- (id)value
{
return value;
}
- (void)setValue:(id)aNewValue
{
if (aNewValue != value) {
[value release];
value = [aNewValue retain];
}
}
Okay, you can argue about the implementation details here, e.g. the if-clause in the setter is optional, I could also implement a setter like this:
[aNewValue retain];
[value release];
value = aNewValue;
This will work fine, even if aNewValue equals value, but it causes an unnecessary retain/release and those are certainly not the fastest operations, since they will either involve locks (rather expensive) or at least atomic operations (still somewhat expensive and have a negative impact on overall system performance of multicore systems, since they might for example have to block the CPU bus to guarantee atomic access across all cores and that means other cores are not be able to access main memory during such an operation).
The code above already reveals a huge problem: When I read the terms "atomic" and "nonatomic", I certainly expect one to use a lock (or at least atomic operations of some kind) and the other one not. This is no big surprise. What is a big surprise though, is the fact that one version extends the lifetime of an object beyond the lifetime of its "owner", while the other one won't. This has *NOTHING* to do with wether an operation is atomic or not!
E.g. consider the following code:
ObjectCreator oc = [[ObjectCreator alloc] init];
id value = [oc value];
[oc release];
[value someMethod];
In case a) this will work just fine, however in case b) this code might *CRASH* my app! This is a fact not obvious to many developers. The nonatomic attribute makes getters behave like "getters" of NSArray or NSDictionary, which do not extend lifetime of returned objects beyond their own lifetime, while normal, atomic getters do the "retain+autorelease dance". This is something that should be written on the very top of Apple's doc in bold letters with a font size of 18 pt.
Unfortunately a) and b) are the only obvious cases, already c) and d) are not really explained in detail. One thing that seems obvious is c) and d) use "copy" instead of "retain" in their setters. However, what about "getters"? Do they use "copy" there as well? Do they use retain+autorelease? Do they just return the values? Are the getters equal to the getters a) and b) for "copy" properties?
Similar questions arise for e) and f). E.g. will e) return the values retain+autorelease, even though the setters don't use retain? And how does nonatomic make any difference for "assign" properties? "Assigning" a pointer is guaranteed to be atomic anyway by the complier, at least for 32 bit pointers on i386 architecture when using GCC. I guess the same holds true for 64 bit pointers on x86_64 architecture (so I had to re-read the GCC specification to ensure that fact). Is the nonatomic attribute ignored for "assign" properties?
These open questions are what drives me away of using properties, since when I write my getter/setters myself, I know at least the answers to all those questions and the answers will not change either (contrary to the answers for properties, that might change whenever Apple releases a new Objective-C language specification).
Kind regards,
Markus_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden