• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Proper retain/release etiquette
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Proper retain/release etiquette


  • Subject: Re: Proper retain/release etiquette
  • From: Marcel Weiher <email@hidden>
  • Date: Tue, 23 Jul 2002 09:25:15 +0200

On Thursday, January 1, 1970, at 02:26 Uhr, Roarke Lynch wrote:

On Monday, July 22, 2002, at 09:05 PM, Chris Anderson wrote:

1. If my code alloc's an object, it is implicitly retained by me and must be
subsequently released. (Said another way, if I did [[[Foo alloc] init]
retain] I would have to release the object twice for it to deallocate.)

yes, init, copy and retain all increase an objects reference count by one.

-copy and -retain: yes
-init: no!

It is the +alloc that 'increases' the objects reference count, or rather: initializes it.


It is good for any method (with the exception of your init and dealloc methods) to have an equal count of (init, copy or mutableCopy, retain) and (release, autorelease).

(adjust as needed)


2. The right place to release contained objects is in the dealloc method.
They should be released and then a [super dealloc] should be done.

Yes, unless you are changing the 'nature' of a contained object. i.e

- (void)setVal:(id)newVal {
[val autorelease];
val = [newVal copy];
}

That doesn't affect the part about releasing in your dealloc.


3. If I got a new object from the system frameworks via any method but
'alloc', it will get implicitly autoreleased, so I have to retain it if I
want it to persist beyond the next RunLoop cycle.

If the object is created using a convience method, i.e [NSArray arrayWithObjects:objOne, objTwo, nil] the object (if the method is written correctly is autoreleased before it is returned to you. So you should not release it.

It may or not be autoreleased, all you need to know and can rely on is that it is not owned by you and you need to retain it if you want it keep it around, and do *not* need to release it if you don't want to keep it around. Do not rely on such methods actually returning autoreleased objects.

4. It's OK to release objects that were allocated by another thread
(assuming that the other thread properly retained what it still needs.)

I find it generally safer not to, but if you do. Call autorelase not release. This delays the release call until the end of the run loop, allowing the object to still be used in other areas of the app.

This is probably not a good idea, because you have introduced a timing-dependent bug: the object may be deallocated while still in use depending on how quickly you get done with event processing in this thread.

If a thread wishes to use such an object, *it* should retain/autorelease it so it sticks around until that thread is done with it.


5. Similarly, auto-release pools in multiple threads won't auto-collide even
if they contain some of the same objects.

I believe that there should generally only be one autorelease pool, special cases excluded.

No. Each thread has at least one autorelease pool. Having sub-pools, though often not necessary, is not something to be discouraged.

7. If I hand an object to a system framework method, the docs for it ought
to tell me explicitly if the framework is ever then going to release or
retain that object (which it usually doesn't.)

They generally don't modify your object (including its reference count) if they are written correctly.

With some exceptions, the framework will retain your object (increase its reference count) if it stores the reference somewhere.

8. A "retain chain" must not loop - i.e. Object ownership should be
uni-directional.

Yes. If you have a retain-cycle, you have a memory leak. You should try to avoid them in the design phase by finding a part of the cycle that doesn't need to be retained because you know there is a retain (Example: subviews don't retain their superviews because they know they are being retained by their superview).

If you cannot do this by design, you will have to find a way to break the cycle or live with the leak.

9. One should not attempt to re-use objects by re-initing them.

no.

No which way? Anyway, you can design your objects to be re-initializable. I do it all the time, and the MPWObjectCache ( in MPWFoundation ) is designed to work with re-initializable objects. I wouldn't rely on other objects to be re-initializable.

10. It is bad practice to do: id bar = [Foo alloc]; [bar init]; because init
might hand back a different object than the original alloc did.

Yes. Or even return nil. Another factor is reading the code. id bar = [[Foo alloc] init]; is the idiomatic way of doing it, so a reader will stumble over your code and wonder why you did it that way. If there is no reason, the reader might be reasonably worried about the rest of the code.

This is programmatically similar to nesting the two i.e id bar = [[Foo alloc] init]. So i think it makes no difference.

Yes it does. Think about -init returning nil.

Marcel
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Prev by Date: NSString stringWithContentsOfURL
  • Next by Date: Re: Document App: IB connections 101
  • Previous by thread: Re: Proper retain/release etiquette
  • Next by thread: Re: Proper retain/release etiquette
  • Index(es):
    • Date
    • Thread