• 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: Ondra Cada <email@hidden>
  • Date: Tue, 23 Jul 2002 09:42:14 +0200

On Tuesday, July 23, 2002, at 03:05 , 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.)

Also, +new, -copy, and -mutableCopy return "implicitly retained" objects.

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.

Yup. Just for completeness, of course if the application logic needs that,
you can release it any time, just don't forget to nil the outlet:

...
-(void)dontNeedFoobarAnymore {
[foobar release]; foobar=nil;
}
...
-(void)dealloc {
...
[foobar release];
...
[super dealloc];
}

3. If I got a new object from the system frameworks via any method but
'alloc',

As said above, also, +new, -copy, and -mutableCopy return newly created objects, which you have to release.

it will get implicitly autoreleased, so I have to retain it if I
want it to persist beyond the next RunLoop cycle.

More precisely, beyond the scope of the current autorelease pool. Which is normally indeed one pass though the event loop; you might change that yourself, though:

id foobar=nil;
NSAutoreleasePool *pool=[[NSAutoreleasePool alloc] init];
...
foobar=[WhataverClass whateverWithSomething...];
...
[pool release];
// foobar is *NOT* valid here!

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

Presumed you retained them before, that is ;)

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

Right, and...

On Thursday, January 1, 1970, at 02:26 , Roarke Lynch wrote:
I believe that there should generally only be one autorelease pool, special cases excluded.

...of course, each thread needs its own autorelease pool.

6. Objects that get added to a framework collection object (such as an
NSArray) will be retained by the collection, so they should be released by
the application after adding them if there are no references elsewhere.

Yup, or autoreleased just before, which is (very slightly) less efficient,
but might be sometimes much more convenient.

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 should, but generally don't. You should design your applications and classes so that you don't care.

BTW, some things are still mysterious, like NSTimers. Who really owns them,
anyway? Are they autoreleased when they are invalidated or expire? Should I
release them immediately if all I want is to get the firing message later?

Sorry, dunno. Somehow, I've never needed them -- in my apps, the ole good -performSelector:withObject:afterDelay: was always quite sufficient... ('course it internally uses an NSTimer, but it does it -- presumably -- the proper way ;)

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

Otherwise there's a leak.

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

Not really part of retain/release etiquette, but right.

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.

ditto

Did I mess up here, or miss something?

Well, since it is a very very common bug, I would explicitly add that the pattern

// *WRONG*
id foo=[[Xyz alloc] init];
// other code here
[foo release];

is bound to leak as soon as the "other code" happens to raise. Therefore, the proper pattern is

// *RIGHT*
id foo=[[[Xyz alloc] init] autorelease]; // or just [Xyz xyz], if available
// other code here

or, if you have very hard reasons not to autorelease, you need to use NS_DURING/NS_HANDLER/NS_ENDHANDLER.
---
Ondra Cada
OCSoftware: email@hidden http://www.ocs.cz
private email@hidden http://www.ocs.cz/oc
_______________________________________________
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.
  • Follow-Ups:
    • Re: Proper retain/release etiquette
      • From: Roarke Lynch <email@hidden>
References: 
 >Proper retain/release etiquette (From: Chris Anderson <email@hidden>)

  • Prev by Date: Re: Document App: IB connections 101
  • Next by Date: Creating an automatic build number with PBX?
  • Previous by thread: Re: Proper retain/release etiquette
  • Next by thread: Re: Proper retain/release etiquette
  • Index(es):
    • Date
    • Thread