Eduardito
Eduardito

Reputation:

Should I explicitly release?

I currently have an array of strings, I'm getting a NSString object from this array by calling the -componentsJoinedByString: method. Example:

NSString *someString = [[NSString alloc] initWithString: [myStrings componentsJoinedByString:@","];

Since -componentsJoinedByString: returns me an NSString, I'm assuming that it is not "owned" by me, therefore what I just did should be ok? or do I have to do this:

NSString *toDelete = [myStrings componentsJoinedByString:@","];

NSString *someString = [[NSString alloc] initWithString:toDelete];
[toDelete release];

Help with clarifying this is much appreciated!

Upvotes: 1

Views: 737

Answers (5)

morningstar
morningstar

Reputation: 9162

You probably don't need more than:

NSString *someString = [myStrings componentsJoinedByString:@","];

componentsJoinedByString: returns an object you don't own, but you can use it at least for the rest of the method, so it's good for local variables.

NSString *someString = [[NSString alloc] initWithString: [myStrings componentsJoinedByString:@","]];
NSString *someString = [[myStrings componentsJoinedByString:@","] copy];

Those two are roughly equivalent. You are correct that you don't need to release the return value of componentsJoinedByString:, so you don't need to keep a reference to it long enough to do so. You can get it and use it in the same expression like that. Objective C's memory management patterns help you write pretty code like that instead of having to declare a lot of extra local variables and write a lot of lines of code just for memory management.

But neither of those are very useful. No other code has access to the object returned from componentsJoinedByString:, so there's no reason to make a private copy. The only reason to do the above is if you want to own the object, in which case the simpler way to gain ownership of it is to send it a retain message.

NSString *someString = [[myStrings componentsJoinedByString:@","] retain];

or

NSString *someString = [myStrings componentsJoinedByString:@","];
[someString retain];

You would do that if you want to keep the object around longer, but usually only if assigning it directly to an instance variable. If assigning it to a property, most properties are declared retain, which means they do the retain for you.

Upvotes: 0

Mike Abdullah
Mike Abdullah

Reputation: 15013

Do you need to make use of this string later outside of this method? If so, you probably want to assign it to an instance variable, so do this:

someStringIVar = [[myStrings componentsJoinedByString:@","] copy];

Otherwise, if it's for temporary use within the method only, do this:

NSString *someString = [myStrings componentsJoinedByString:@","];

Either way, there is absolutely no need for the ridiculous -initWithString: and +stringWithString: calls that people seem far too keen on.

Upvotes: 0

Abizern
Abizern

Reputation: 150785

Marc answered the first part while I was typing.

The second set of expressions you have is not required and is bad practice; You are sending a release message to the string toDelete which you do not own. You are declaring a pointer to the the string, but did not alloc the memory for the string being pointed to (nor did you call retain on it) so you don't own the object that toDelete is pointing to.

Upvotes: 0

Marc Charbonneau
Marc Charbonneau

Reputation: 40513

The first example you wrote is correct, although in practice it would be clearer just to write NSString *someString = [[myStrings componentsJoinedByString:@","] copy]; (note that this will be retained, so you will have to release it at some point in the future.

If you're having trouble with memory management, this page might help. It's not too hard to learn the rules, but you're going to run into a lot of problems until you do.

Upvotes: 4

dreamlax
dreamlax

Reputation: 95405

You only need to retain the string returned by componentsJoinedByString: it if it will be used outside the current method's scope.

Upvotes: 0

Related Questions