views:

808

answers:

2

I need to post a notification using postNotificationName:object:userInfo: method, and I'm passing a custom class FileItem in as userInfo so I can obtain it on the other end. Should I use autorelease like this

FileItem *item = [[[FileItem alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];
[item release];

or can I just alloc and then release the object immediately after passing it to the default notification center?

FileItem *item = [[FileItem alloc] init];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];
[item release];

I'm trying to get convention here as in can I assume that whenever I pass an object as parameter in a message to another object, the receiving object would do a retain if it needs to, and that I can safely release the said parameter?

Thanks in advance.

+2  A: 

The second option is the correct one. You could also just do the following:

FileItem *item = [[[FileItem alloc] init] autorelease];
[[NSNotificationCenter defaultCenter] postNotificationName:@"dataReceived" object:self userInfo:item];

The conventional wisdom is that for every alloc, copy, or retain, you need a corresponding release (or autorelease). Doing anything more is almost guaranteed to result in your object being overreleased.

Matt Ball
Thanks. It's much clearer to me now. I often get confused though when I declair a NSString * in the .h file, release the NSString * in the dealloc method, but in the init file there is no alloc / copy / retain, only something like stringObject = [NSString stringWithFormat@"....."];Can you tell me what's going on in this case?
Ben
In that case, you shouldn't be releasing the string in your dealloc method: No alloc/copy/retain, no release. However, what you may want to do is something like this: stringObject = [[NSString stringWithFormat:@"…"] retain]; and then release stringObject in your dealloc method. This ensures that the string wont go away until you're ready for it to.
Matt Ball
Right, no alloc/copy/retain, no ownership, no release. Thanks.
Ben
I'd add mutableCopy to the list of calls that will need an eventual release.
Abizern
+2  A: 

autorelease just means “send release to this later”. Sending autorelease and then release to the same object is releasing it twice. As Matt Ball says, your latter example and his example are equivalent.

More to the point, you only release what you own. Once you release it, you stop owning it, and should consider it no longer yours. In your first example, after the first release, you've stopped owning that object. The second release is then clearly wrong, because it releases an object you don't own.

And never release an object that some other object owns, unless you also own it.

Peter Hosey
I can see how releasing the object that has already been sent to the autorelease pool can be bad. Thanks for the explaination. I wonder if I should procees with the assumption that everytime I send a message to another object I should assume that the method is going to retain it. Once I passed the object over, I can release it in the next line?
Ben
You shouldn't care whether other objects are going to retain it or not. The question is: Do you own it? If so, you retain or copy it. If not, you don't. And then, later, you release what you own. It's that simple. And an object in a local variable is generally something you don't own; you put the things you own into instance variables, or into collection objects in instance variables.
Peter Hosey
Got it. Thanks again.
Ben