views:

158

answers:

7

I'm sorry to ask such a simple question, but it's a specific question I've not been able to find an answer for.

I'm not a native objective-c programmer, so I apologise if I use any C# terms!

If I define an object in test.h

@interface test : something {
    NSString *_testString;
}

Then initialise it in test.m

-(id)init {
    _testString = [[NSString alloc] initWithString:@"hello"];
}

Then I understand that I would release it in dealloc, as every init should have a release

-(void)dealloc {
    [_testString release];
}

However, what I need clarification on is what happens if in init, I use one of the shortcut methods for object creation, do I still release it in dealloc? Doesn't this break the "one release for one init" rule? e.g.

-(id)init {
    _testString = [NSString stringWithString:@"hello"];
}

Thanks for your helps, and if this has been answered somewhere else, I apologise!!

Steven

+2  A: 

If it's not created with alloc, new, copy, mutableCopy then you're not responsible for releasing it.

This site has some good quick overviews of things like memory management.

Here's a quote from cocoadevcentral:

If you create an object using the manual alloc style, you need to release the object later. You should not manually release an autoreleased object because your application will crash if you do.

Justin
A: 

The rule is if you create an object with new, alloc, copy or you retain it, you need to release it. Objects created in any other way must not be released.

So in your specific case, you would not need to release your string created with stringWithString.

By the way, I would recommend the Cocoa and Objective-C: Up and Running book for learning more about things like this. Great introduction if you are new to Cocoa programming.

jcady
The rule is if you create an object with **new** alloc or copy **or you retain it**, you need to release it. Objects created in any other way **must not be** be released. Fixed it for you.
JeremyP
Thanks. I edited in your clarifications.
jcady
A: 

In the first part of the example you do indeed have to have a release for the string somewhere.

In the second part of the example because its an autoreleased you don't need to call the additional release in the dealloc method. This will actually cause a crash as you are attempting to send a message to something that no longer exists...

James Raybould
+5  A: 

There is a neat acronym to remember what you have to release

N.A.R.C - new, alloc, retain, copy.

sylvanaar
nice, I forgot about that nice little acronym :)
Justin
+2  A: 

Just to clarify things a bit. When you get an object through N.A.R.C. as sylvanaar says you do need to release it. In other cases you are getting an autoreleased object that will be released automatically at some later time. That will be bad in the code you presented here, because you do want this string to stay around at least as long as your object. So you actually need to do an explicit retain to keep it alive for your object.

That is not directly answering your question, but rather anticipating the next one ;-)

Ukko
A: 

If you set an attribute with an autorelease, the object in the attribute can die at anytime beyond the immediate scope. Convenience methods i.e. ones that start with a type: string, array, dictionary etc, return autoreleased objects. You only use autoreleased objects when you don't care whether or not they survive beyond the present scope.

What you really need to do in this case is use accessors, either the synthesized or custom, to manage your retention automatically.

If you do:

@property(nonatomic, retain)  NSString *_testString; // .h
@synthesize _testString; //.m

then in code use the reference form:

self._testString = [NSString stringWithString:@"hello"];

... then the only place you have to release _testString is in dealloc. The compiler will create synthesized accessors which will automatically manage the properties memory for you.

By the way, you should not use underscores for names. Apple reserves underscore names for itself so you can get a naming collision.

TechZen
A: 

On the contrary, you need to retain the object you get from stringWithString:. As you correctly noted, you don't own that object and thus don't need to release it. But because you don't own it, it's free to disappear at any time, leaving you with a crash if you're lucky (and a very odd bug if you're not). So you need to retain the object, and then you do need to release it in dealloc.

All of this is explained very well in the memory management guide. I suggest you read it over a couple of times. It's not very long or difficult, and once you internalize it, you'll never have to wonder again.

Chuck