Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Sure, but can the compiler prove that?


I'm fairly sure that the LLVM compiler is smarter than the smartest Objective-C code I could write, but your mileage may vary.


I'm fairly certain that it doesn't do cross-translation-unit inter-procedure analysis, so it can't tell if, for example, the function from another file that you call does anything special that would make the removal of a retain before passing the object to the function an invalid optimization.

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 :)


Disclaimer: I haven't actually tried playing with this yet, or read the docs, so this is pure speculation:

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.


For 99% of the 99%, yes.

  self.blueView = [[BlueView alloc] init];
  [self.blueView release];
etc


If you took advantage of properties you could do self.blueView = nil; and have the release be done for you.


I believe he IS taking advantage of an auto-retained property, which is why he needs the release... because the property setter has issued its own retain, which will be released when the property is set again...


With synthesized ivars, you must do:

  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 leak


Which for KVO reasons is a really bad way of releasing objects when 'self' is being deallocated.


Hmm, I don't quite follow. I'm new to Cocoa programming and just followed the advice from the book Cocoa up and running.


If anyone does KVO on your object, they will be sent a "property changed" notification when you call self.myvar = nil in your dealloc method.

It'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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: