Unless they're doing some pretty strong analysis to remove redundant reference operations.
Unless they're doing some pretty strong analysis to remove redundant reference operations.
It doesn't know that the object is only used in a thread-local context, so in many cases (eg, function args) it might not be able to assume that there is no concurrent refcounting action going on elsewhere, which eliminates other optimizations.
By definition, compilers have to be conservative about what callers can do, when humans can simply say "This function is not thread safe", or similar.
This is one reason that "real" GC is generally used instead of reference counting in all high performance garbage collected language. (In throughput-oriented systems, the GC is even a stop-the-world GC, since that removes quite a bit of concurrency/atomic operation overhead).
The other big one is that you need a garbage collector anyways if you want things to work in the presence of cycles.
EDIT: Perhaps someone with a Mac and access to this compiler can post some output of code with this feature enabled. I'd be curious to see what sort of output the compiler actually gives.
This speculation is annoying :)
It may not need to do any kind of complicated proving or cross-unit analysis, and instead opt to simply rely on the fact that every good Objective-C citizen follows the same social naming conventions. Things coming back from methods with "alloc", "copy", or "new" in the name are owned by the current method and need to be disposed of properly (release it at the end of the method, or if it escapes this method, add it to the autorelease pool). Everything else can be assumed to be taken care of and we need only bump the retain count if it's getting assigned to something with a scope larger than the current method.
It wouldn't catch everything, but it could be made predictable in behavior and eliminate a large percentage of the boilerplate.
self.blueView = [[BlueView alloc] init];
[self.blueView release];
etcIt's quite likely that whoever gets notified of the property change will attempt to access your object, but now your object is in a half-destroyed state.
self.blueView = [[BlueView alloc] init];
[self.blueView release];
When you allocate to get the proper retain count; I can demonstrate why by using a temporary variable: BlueView* bv = [[BlueView alloc] init];
//Retaincount = 1
self.blueView = bv;
//Reaincount = 2
[self.blueView release];
//retainCount = 1
And then in dealloc [self.blueView release];
//retainCount =0;
So in dealloc I could call your function, but there are things in various object packing schemes (KVO most importantly) where calling the setter like that screws stuff up. It's better to just call the getter (which should be side effect free) and release the returned object.So looking at retain counts in the original example:
self.blueView = [[BlueView alloc] init];
//Retain count 2
[self.blueView release];
//Retain count 1
and in dealloc [self.blueView release];
//Retain count 0
If I just did what you said, I'd get: self.blueView = [[BlueView alloc] init];
//Retain count 2
and in dealloc self.blueView=nil;
//Retain count 1, rut ro, memory leakGC is still supported on MacOS X.
If a bus lock degrades your performance too much, either change your algorithm, or isolate that section of code and do it in another language that doesn't suffer the same performance issues.