Uli's Web Site
[ Zathras.de - Uli's Web Site ]
Other Sites: Stories
Abi 2000
Stargate: Resurgence
Lost? Site Map!
     home | blog | moose | programming | articles >> blog

 Blog Topics

15 Most Recent [RSS]

 Less work through Xcode and shell scripts
2011-12-16 @600
 iTunesCantComplain released
2011-10-28 @954
 Dennis Ritchie deceased
2011-10-13 @359
 Thank you, Steve.
2011-10-06 @374
 Cocoa Text System everywhere...
2011-03-27 @788
 Blog migration
2011-01-29 @520
 All you need to know about the Mac keyboard
2010-08-09 @488
 Review: Sherlock
2010-07-31 @978
 Playing with Objective C on Debian
2010-05-08 @456
 Fruit vs. Obst
2010-05-08 @439
 Mixed-language ambiguity
2010-04-15 @994
 Uli's 12:07 AM Law
2010-04-12 @881
 Uli's 1:24 AM Law
2010-04-12 @874
 Uli's 6:28 AM Law
2010-04-12 @869
 Uli's 3:57 PM Law
2010-04-12 @867


The Why of release and retain

This is an excerpt from a message I sent to Cocoa-Dev - I just realised I forgot to Reply to All and thought this info might be handy for someone googling for help:

Cocoa memory management is fairly simple: You have alloc/init to create an object, and release to dispose of it again. If you get an object someone else created, you can call retain or copy on it to make sure it stays around until you don't need it anymore, which you indicate by calling release. There are several variants of init and copy, like initWithData: and mutableCopy, but for those the rule is the same.

However, often, people check the retainCount of their objects and try to add as many release calls as are needed to bring the retain count back down to zero. There's a subtle mistake in there. You're not supposed to worry about the retain count, you only have to worry about matching up your alloc/init, copy and retain calls with that many releases. Why? Easy:

The whole point of retain is that several objects can share access to another object without having to know. The retain count counts all owners, and thus can only be used as a hint when debugging if you know who the other owners are and how often they retain an object with 100% certainty. Which you never do. [1]

Let's assume you have an NSScanner and you're passing it a string you created. In this case, the scanner may be retaining your string, and since scannerWithString: contains neither retain, nor init, nor copy, you can assume that it is owned by someone else (like the current autorelease pool). So, that the retain count reaches 2 is probably due to the scanner holding on to its string.

When you release the string a second time to make its retain count hit zero, what you effectively do is kill the text that the scanner still expects to be there. When the owner of the scanner releases the scanner, the scanner will in turn perform its duty and try to release the string. Since you already released it, the scanner is talking to a zombie object, and your program will generate a bus error or bad access signal (if you're lucky -- if you're not, the memory where your textViewContents used to be hasn't been reused yet and still contains the old values and your code will just start behaving oddly ... which is the most engaging kind of bug to track down).

So, match up your calls, don't mess with the retain count.

1) Yes, strictly spoken there are situations in which the other owners can be known, but the number of retains on an object may change from system version to system version, and thus it is very unhealthy to rely on that. And it's easy to think you know all owners and then realize when your app crashes that you overlooked some delegate or internal object that does an additional retain.

Reader Comments: (RSS Feed)
No comments yet
Or E-Mail Uli privately.

Created: 2005-09-19 @717 Last change: 2005-09-19 @728 | Home | Admin | Edit
© Copyright 2003-2023 by M. Uli Kusterer, all rights reserved.