Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 545 Vote(s) - 3.58 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Understanding reference counting with Cocoa and Objective-C

#1
I'm just beginning to have a look at Objective-C and Cocoa with a view to playing with the iPhone SDK. I'm reasonably comfortable with C's `malloc` and `free` concept, but Cocoa's references counting scheme has me rather confused. I'm told it's very elegant once you understand it, but I'm just not over the hump yet.

How do `release`, `retain` and `autorelease` work and what are the conventions about their use?

(Or failing that, what did you read which helped you get it?)
Reply

#2
Objective-C uses [Reference Counting](

[To see links please register here]

), which means each Object has a reference count. When an object is created, it has a reference count of "1". Simply speaking, when an object is referred to (ie, stored somewhere), it gets "retained" which means its reference count is increased by one. When an object is no longer needed, it is "released" which means its reference count is decreased by one.

When an object's reference count is 0, the object is freed. This is basic reference counting.

For some languages, references are automatically increased and decreased, but objective-c is not one of those languages. Thus the programmer is responsible for retaining and releasing.

A typical way to write a method is:

id myVar = [someObject someMessage];
.... do something ....;
[myVar release];
return someValue;

The problem of needing to remember to release any acquired resources inside of code is both tedious and error-prone. Objective-C introduces another concept aimed at making this much easier: Autorelease Pools. Autorelease pools are special objects that are installed on each thread. They are a fairly simple class, if you look up NSAutoreleasePool.

When an object gets an "autorelease" message sent to it, the object will look for any autorelease pools sitting on the stack for this current thread. It will add the object to the list as an object to send a "release" message to at some point in the future, which is generally when the pool itself is released.

Taking the code above, you can rewrite it to be shorter and easier to read by saying:

id myVar = [[someObject someMessage] autorelease];
... do something ...;
return someValue;

Because the object is autoreleased, we no longer need to explicitly call "release" on it. This is because we know some autorelease pool will do it for us later.

Hopefully this helps. The Wikipedia article is pretty good about reference counting. More information about [autorelease pools can be found here](

[To see links please register here]

). Also note that if you are building for Mac OS X 10.5 and later, you can tell Xcode to build with garbage collection enabled, allowing you to completely ignore retain/release/autorelease.
Reply

#3
Joshua ([#6591][1]) - The Garbage collection stuff in Mac OS X 10.5 seems pretty cool, but isn't available for the iPhone (or if you want your app to run on pre-10.5 versions of Mac OS X).

Also, if you're writing a library or something that might be reused, using the GC mode locks anyone using the code into also using the GC mode, so as I understand it, anyone trying to write widely reusable code tends to go for managing memory manually.


[1]: #6591
Reply

#4
> [Matt Dillard wrote](

[To see links please register here]

):
>
> return [[s autorelease] release];

Autorelease does *not* retain the object. Autorelease simply puts it in queue to be released later. You do not want to have a release statement there.
Reply

#5
If you're writing code for the desktop and you can target Mac OS X 10.5, you should at least look into using Objective-C garbage collection. It really will simplify most of your development — that's why Apple put all the effort into creating it in the first place, and making it perform well.

As for the memory management rules when not using GC:

- If you create a new object using `+alloc/+allocWithZone:`, `+new`, `-copy` or `-mutableCopy` or if you `-retain` an object, you are taking ownership of it and must ensure it is sent `-release`.
- If you receive an object in any other way, you are _not_ the owner of it and should _not_ ensure it is sent `-release`.
- If you want to make sure an object is sent `-release` you can either send that yourself, or you can send the object `-autorelease` and the current _autorelease pool_ will send it `-release` (once per received `-autorelease`) when the pool is drained.

Typically `-autorelease` is used as a way of ensuring that objects live for the length of the current event, but are cleaned up afterwards, as there is an autorelease pool that surrounds Cocoa's event processing. In Cocoa, it is _far_ more common to return objects to a caller that are autoreleased than it is to return objets that the caller itself needs to release.
Reply

#6
Lots of good information on cocoadev too:

* <a href="http://www.cocoadev.com/index.pl?MemoryManagement">MemoryManagement</a>
* <a href="http://www.cocoadev.com/index.pl?RulesOfThumb">RulesOfThumb</a>

Reply

#7
As ever, when people start trying to re-word the reference material they almost invariably get something wrong or provide an incomplete description.

Apple provides a complete description of Cocoa's memory management system in [Memory Management Programming Guide for Cocoa][1], at the end of which there is a brief but accurate summary of the [Memory Management Rules][2].




[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#8
As several people mentioned already, Apple's [Intro to Memory Management][1] is by far the best place to start.

One useful link I haven't seen mentioned yet is [Practical Memory Management][1]. You'll find it in the middle of Apple's docs if you read through them, but it's worth direct linking. It's a brilliant executive summary of the memory management rules with examples and common mistakes (basically what other answers here are trying to explain, but not as well).


[1]:

[To see links please register here]

Reply

#9
There's a free screencast available from the iDeveloperTV Network

[Memory Management in Objective-C][1]


[1]:

[To see links please register here]

Reply

#10
The answers above give clear restatements of what the documentation says; the problem most new people run into is the undocumented cases. For example:

* **Autorelease**: docs say it will trigger a release "at some point in the future." WHEN?! Basically, you can count on the object being around until you exit your code back into the system event loop. The system MAY release the object any time after the current event cycle. (I think Matt said that, earlier.)

* **Static strings**: `NSString *foo = @"bar";` -- do you have to retain or release that? No. How about

-(void)getBar {
return @"bar";
}

...

NSString *foo = [self getBar]; // still no need to retain or release

* **The Creation Rule**: If you created it, you own it, and are expected to release it.

In general, the way new Cocoa programmers get messed up is by not understanding which routines return an object with a `retainCount > 0`.

Here is a snippet from [Very Simple Rules For Memory Management In Cocoa][1]:

> *Retention Count rules*
>
> * Within a given block, the use of -copy, -alloc and -retain should equal the use of -release and -autorelease.
> * Objects created using convenience constructors (e.g. NSString's stringWithString) are considered autoreleased.
> * Implement a -dealloc method to release the instancevariables you own

The 1st bullet says: if you called `alloc` (or `new fooCopy`), you need to call release on that object.

The 2nd bullet says: if you use a convenience constructor *and you need the object to hang around* (as with an image to be drawn later), you need to retain (and then later release) it.

The 3rd should be self-explanatory.


[1]:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through