views:

703

answers:

3

I am defining a number, as follows:

NSNumber *nn0 = [NSNumber numberWithInt:0];

It works fine without any alloc. My understanding is that if I use numberWithInt, alloc and init are called automatically.

If I try to release at the end of my function, I run into problems:

[nn0 release];

I get a runtime error.

My question is: if I use numberWithInt to initialise the NSNumber, do I have to do any memory management on it?

+5  A: 

Just follow the core memory-management rule: If you "own" the variable, you have to eventually relinquish ownership. You take ownership by: creating the object (alloc/new/copy) or specifically taking ownership (retain). In all these cases, you're required to release it.

If you need the object to stick around, you need to take ownership of it. So if you know you only need the number for this method (like to pass it into an array or whatever), use the convenience method and just leave it at that. If you want to keep the number for some reason (and instance variable, for example), then you can safely alloc/init it.

If you release something that you don't own, you will get a runtime error.

Jason Coco
+10  A: 

The "convenience constructors" for a lot of types produce an object that is automatically "autoreleased" - i.e. the new object will be retained by the current NSAutoreleasePool. You don't need to manually release these objects - they will be released when the current NSAutoreleasePool is released/drained.

See this page for a description of convenience constructors, and how to mange the memory for these.

http://www.macdevcenter.com/pub/a/mac/2001/07/27/cocoa.html?page=3

Andy White
Just curious why this is getting downvotes? Is this not accurate? I'm fairly new to mac dev, just trying to offer some help.
Andy White
It's probably due to terminology. Basically, anything returned by a convenience method (or any method outside your control) is not considered to be "autoreleased". Rather it's considered to be "not owned" by you. The point being, how memory is actually managed is not relevant on objects you don't "own".
Jason Coco
I marked this response as the correct one due to the link. Jason, your response was also excellent, I wish I could mark both as the correct answer.
deadcat
You're getting a down vote because some people are petty.
Alex Reynolds
Yeah, I gave him +1 just because i bet it has to do with something silly like the terminology.
Jason Coco
@deadcat - i figured :) links are always useful!
Jason Coco
@Jason, thanks for the clarification. Isn't the normal mechanism for the convenience constructors to autorelease the objects though? How else would the method guarantee that the object is released if you don't take ownership of (retain) it yourself? I get your point about ownership not necessarily implying autorelease though.
Andy White
+4  A: 

The rule is simple, with very few exceptions:

If the selector returning an object has the word "new", "alloc", "retain" or "copy" in it, then you own the returned object and are responsible for releasing it when you are finished.

Otherwise you do not own it and should not release it. If you want to keep a reference to a non-owned object, you should call -[NSObject retain] on that instance. You now "own" that instance an must therefore call -[NSObject release] on the instance when you are done with it. Thus you do not own the instance returned by -[NSNumber numberWithInt:] and should not call -release on it when you are done. If you want to keep the returned instance beyond the current scope (really beyond the lifetime of the current NSAutoreleasePool instance), you should -retain it.

In RegEx terms, Peter Hosey lays it out very nicely in his blog. You own the returned object instance if the method selector matches this regex:

/^retain$|^(alloc|new)|[cC]opy/

Of course, the definitive reference is the Memory Management Programming Guide for Cocoa.

Barry Wark
The only exception to that regex I've found: NSData +dataWithBytesNoCopy:length:[freeWhenDone:], which returns an autoreleased NSData despite its name. Even Build-and-Analyze/clang checker get that one wrong.
qwzybug