Object autorelease point on Mac OS X 10.4 and 10.5

How many of you gave up Mac OS X 10.4?
In my case, I need to keep supporting it. So, I always choose the common methods and functions between OS X 10.4 and 10.5. However, sometimes the same methods on 10.4 work differently than those on 10.5 do.

However, recently I noticed difference in behaviour of autorelease pool.
For example, let’s say that there is an object called MainObject. As its member variable, there is a pointer to another object called ObjectA. The ObjectA also has a member variable, mMainObject, to point the MainObject. So, let’s say that init method of ObjectA takes a pointer to an MainObject. Also the ObjectA exists until the program itself quits.

@interface ObjectA
    MainObject *mMainObject;

- (id)initWithMainObject:(MainObject *)theObject;

@implementation ObjectA
- (id)initWithMainObject:(MainObject *)theObject
    mMainObject = theObject;

    return self;

The object passed through theObject parameter is marked to be autoreleased. In other words, it was created with so-called convenient method or its autoreleased method is explicitly called. So, it will be autoreleased if the object is not considered to be used anymore.

In initWithMainObject method, it is not retained. Why isn’t it retained? It is because the instance fo the ObjectA will not be deallocated while the program is running, anyway.

Then what will happen?
It is safe to retain an object which is marked to be autoreleased. However in this case, mMainObject will be always valid and there is no way that the runtime regards that the object pointed by mMainObject is not used anymore. So, I expected that the mObject is not released.

On Mac OS X 10.4, I found out that it was not safe. It should be retained to work correctly.

Although an instance of the ObjectA still exists, it is released because it is marked as autoreleased. ( It is created by “convenience methods” or is marked as “autoreleased”. ) But it should not be autoreleased because the object is still pointed by the mMainObject and the instance of the ObjectA still exists.
On OS X 10.4, it is autoreleased even though the mObject still points to the object in a still-alive instance of ObjectA class.

However of Mac OS X 10.5, the object is not autoreleased. It seems to work as I assumed. So, the above code is safe on 10.5.
So, to write safe code for the both version, it should be retained.

I hope that there will be no this kind of difference in Snow Leopard.

NOTE: As you can see from Mr. Monroe’s comment, some people can be confused about what this post is about. So, I added additional note as “Added Note” to make things clearer.

NOTE : This post is revised to reduce confusion further.
Thank you, Mr. Monroe. Thanks to you, I read this post again and found out that its text can be confusing. It was written while I was preparing my dinner. So, the text didn’t flow smoothly. I’m sorry about that.


6 responses to this post.

  1. Don’t you have GC enabled on 10.5? That would explain it… When you turn GS *support* on, you still can run it on 10.4, but 10.4 doesn’t have a GC, so you still need to include all retains and releases, but these messages are ignored on 10.5 and GC is used instead… So the same code is generally “interpreted” otherwise on 10.4 and 10.5 which leads to crashes on 10.4 and no crashes on 10.5…


    • Posted by jongampark on May 14, 2009 at 11:31 PM

      Hello. Thank you for leaving a message.
      I don’t enable GC on 10.5 usually. The project I have worked on is targeted for 10.4 and doesn’t use GC.

      It is not about “GC” either. It is about autorelease. If I remember it correctly, there was some problem with autorelease point on 10.4. In short, it is about how the Obj-C runtime of different version handles autorelease differently.


  2. It can be targeted as 10.4 and the option GCC_ENABLE_OBJC_GC = supported – that means it uses it if it can…


    • Posted by jongampark on May 15, 2009 at 7:32 AM

      I know that the GC can be set even for a project targeted as 10.4. But as I said, the project doesn’t use GC.
      If you can’t believe me, I will confirm this for you.
      “Objective-C Garbage Collection(GCC_ENABLE_OBC_GC)” : Unsupported

      I think you don’t understand what my post is about.


  3. Posted by mmw on May 24, 2010 at 10:48 PM

    Hello JongAm, you are absolutely right, the GC has nothing to do with this behavior, I don’t know your experience with Obj-C but seems not to be quiet long, that’s not a critic:

    1- the two runtimes are different:

    Obj-c1: the table holding the references was itself an Obj-C table, here some caveats regarding circular references (tree) and the pool, weak references.

    Obj-c2: the long time mistake has been finally corrected and permit finally to have a stable GC implementation in Obj-C, strong references hashtable.

    2- you are lucky, this behavior might depends on the scope and the nature of the autorelease object e.g an another class member and where and when is created. (initialize)

    3- that’s still a bad practice what you did, guards (e.g retain) do not cost any memory and make the code clearer and make you respect the ownership policy.



    • Posted by jongampark on May 25, 2010 at 7:12 PM

      Thanks for your comment.

      Actually, I always send “retain” message.
      However, I found out different behaviour of memory manager for the both platform.
      So, what I wanted to point out in this post was to suggest people to make it sure to write codes which were to work correctly on the both platform.
      The reason I wrote it was not because I didn’t understand it. :)


Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: