views:

568

answers:

6

I want to create an object in Objective C but I don't hold a reference to it.

Is it allowed to let the object control its own lifetime by calling [self release]?

In case you're wondering why I need this: I want to create an object that subscribes to some notifications, but after a while the object is no longer needed and should go away.

So, is the following allowed?

- (void) destroyMyself {
   [[NSNotificationCenter defaultCenter] removeObserver:self];

   [self release];
}
+2  A: 

It's legal, but be careful. You want to be sure nothing else is going to send you a message after you release yourself.

I've done this kind of thing for a faulting scheme back before we had CoreData.

NSResponder
+2  A: 

Well part of the protocol is that if you send release to self, then you should have sent retain once as well, which I suppose you do. Then there is nothing fishy. I mean the allocing code must be able to control the lifetime of your instance; it itself can only prolong its life, never make it shorter (since making it shorter, then you'd suddenly leave the allocing owner of the instance with an invalid pointer).

kaizer.se
Are you saying I should call [self retain] in the init method?
Philippe Leybaert
basically yes. Perhaps you should make users of the class use an autorelease method like [ListenerClass listenerWithParam:param] since the user might as well not retain it. But requiring the class' release match up by a call to alloc/retain by the class user is *broken*
kaizer.se
No, you shouldn't send -retain to self, because you already have a non-zero retain count after +alloc. Always balance your retains and releases. If you send +alloc, +new, -copy or -retain, balance them with -release or -autorelease.
NSResponder
NSResponder: That is exactly the point. If he wants an *internal* release call, he *has to* send retain once as well.
kaizer.se
NSResponder: An instance could obviously not instantiate itself, so a user must send alloc + init to it; and *has to* send release or autorelease later on. So the +alloc message is *not for the class implementor* to balance
kaizer.se
I want the class to extend its own life, so I have no other choice than to call retain on self. (because the creator of the object could release the object, which - according to best practices - it should)
Philippe Leybaert
In the case you describe, I would follow the example of NSTimer, where the user of your class would obtain an instance using a convenience method. NSTimer instances destroy themselves when they get an -invalidate message.
NSResponder
+2  A: 

To quote the great philosopher Alicia Silverstone, "I had an overwhelming sense of ickiness" when I read that. But I couldn't really tell you why.

I think I would use autorelease rather than a simple release since you're still executing code in self when you call it, but other than that I can't think of any technical reasons why it wouldn't work.

Stephen Darlington
That, or: [self release]; self = nil;
Darren
+4  A: 

I have done this many times before, it is perfectly fine to do, as long as you are doing it for the right reasons.

For example, The best example of its usage is when you create an object that goes off to download a url. The object sits in memory while downloading the url, then sends a message to its delegate saying the data is ready (or url couldn't be downloaded). Once its message has been sent it destroys itself as its no longer needed.

This is useful when the code that creates the "download" object doesn't care if the download completes or not.

Jacob
+1  A: 

And I will use [self autorelease] instead of [self release]. Because usually it's called in

- (void)aMethod
{
    [self.delegate aDelegateMethod:self];
    [self release];

//If you add code related to self here, after [self release], you are making a huge mistake.
}

If I use [self autorelease], I can still do something after autorelease.

Mike Chen
+2  A: 

The rules are simple. You should only release an object if you own it. i.e. the object was obtained with a method starting "new" or "alloc" or a method containing copy.

Cocoa Memory Management Rules

An object must not therefore do [self release] or [self autorelease] unless it has previously done [self retain].

JeremyP
amen! ............
Philippe Leybaert