Re: initWithCoder / unarchiveObjectWithData Memory Management Question
Re: initWithCoder / unarchiveObjectWithData Memory Management Question
- Subject: Re: initWithCoder / unarchiveObjectWithData Memory Management Question
- From: Uli Kusterer <email@hidden>
- Date: Sat, 20 Feb 2010 11:32:32 +0100
On 20.02.2010, at 07:47, Thomas Wetmore wrote:
> (error handling removed), has myObject been retained, or must I now retain it. The unarchiveObjectWithData class method causes myObject's class's initWithCoder object method to run. I assume that initWithCoder obeys memory management rules and returns a newly alloc'ed and retained object. Does the unarchiveObjectWithData method return that retained object unaltered, or does it autorelease it first, so that the unarchiveObjectWithData method obeys the usual convention of class factory methods to return autoreleased objects?
The memory management contract is about the name of the methods *you call*, and about *their* results. One of the tenets of object-oriented programming is "encapsulation", which, to put it simply, means that you only care about the face your class presents to the outside, and the class is free to do internally what it wants. The beauty of encapsulation is that Apple can change the internal details of any class without breaking your code, e.g. to make it faster or to make it run on new hardware.
So, don't try to guess what the class may be doing internally. Just listen to what it tells you on the outside. And the outside is the method name, and to extract the information from the method name, you see whether it matches any of the criteria in the memory management rules (since people often get them wrong, we're not allowed to rephrase them on this list, so I'll give you the link instead: http://developer.apple.com/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH).
If it helps you, then yes, to correctly fulfill the contract they enter by naming the method like this, Apple would have to call -autorelease after -initWithCoder: before returning it, in the simplest case. If they didn't, this would be an Apple bug.
Let's take another example, NSUserDefaults's -objectForKey: A very simple implementation would simply load the preferences file from disk each time, create the requested value and return it. If the value was created using alloc/init, it would have to be autoreleased, because the name "objectForKey", doesn't contain the word alloc, new, copy or retain.
However, what Apple in fact does is they load the preferences from disk into a dictionary, and then just change the dictionary. When your app quits or someone calls -synchronize, it writes the dictionary back to the preferences file. Now, since the dictionary already retains the objects, all NSUserDefaults's -objectForKey: does is return the existing object from the dictionary. Since the dictionary is already retaining that object, NSUserDefaults doesn't really have to create/retain the object and autorelease it later, it just hands it out.
This is only possible due to encapsulation: you don't have to guess what is happening inside, because it can be different. If one day Apple switches to a new, very fast and very robust kind of SSD that is fast enough to do the load/write thing right away, or switches from XML plists to a new SQLite-based file format that allows for loading only the bits we want right now, they can change it internally, and start calling alloc again without you having to know about that and having to change your code. They just have to make sure they autorelease.
Cheers,
-- Uli Kusterer
"The Witnesses of TeachText are everywhere..."
http://www.zathras.de
_______________________________________________
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