views:

461

answers:

4

Hi,

I'm looking for a good way to return a string constructed by a NSMutableString avoiding leaking :

eg:

+(NSString *)myMethod{



 NSMutableString *numberToReturn = [[NSMutableString alloc] init];
 [numberToReturn appendString:@"lorem ipsum"];


 return numberToReturn;
}

The leak instrument said I had leak with this variable.

I tried autorelease but it crashes I tried to return a copy or copying the mutablestring into a nsstring but leak still present.

Any idea or trick? I'have a to call this method each time the user type a value into the textfield, so the application crashes due to bad memory management...

thank you

A: 

You should probably return an autorelease-d variable, as you've already mentioned. Can you give more detail as to why that was crashing? Was the caller perhaps then release-ing the variable without having retain-ed it?

It also looks like you're returning an NSString* from this function, although you alloc-ed a NSMutableString, but that should be okay.

Shaggy Frog
NSMutableStrings are NSStrings, so he's fulfilling the contract.
Chuck
I know. I'm just saying that it's usually better to return the type you allocated.
Shaggy Frog
No, it's better to return the least specialized type consistent with the interface contract. What you *actually* return is an implementation detail.
Barry Wark
It's all speculation on our part without knowing more about the context of how the code will be used. If the person calling the function actually needs an MSMutableString and has to alloc one inited from the NSString, you're adding complexity to the client side. That is, if that's the case. In general I just prefer the consistency of returning what I made unless there's a reason not to.
Shaggy Frog
+8  A: 

You should use -autorelease. Your method should be written as:

+ (NSString*)myMethod {
    NSMutableString *stringToReturn = [[NSMutableString alloc] init];
    [stringToReturn appendString:@"lorem ipsum"];

   return [stringToReturn autorelease];
}

If there is a crash, the fault is elsewhere.

Of course, you can make use of factory methods that return an already-autoreleased instance, rewritting your method as

+ (NSString*)myMethod {
  NSMutableString *result = [NSMutableString string];
  [result appendString:@"lorem ipsum"];

  return result;
}

or better yet for your example,

+ (NSString*)myMethod {
    NSMutableString *result = [NSMutableString stringWithString:@"lorem ipsum"];
    //...do something with result;
    return result;
}

Obviously if you method's only purpose is just to return a new string with a string, you can avoid the whole method all together and use [NSMutableString stringWithString:@"lorem ipsum"] if you really need a mutable string.

Barry Wark
Just to clarify the "If there is a crash, the fault is elsewhere." You shouuld make sure you don't release an autoreleased object elsewhere. The string returned from this method will be released when the autoreleasepool is released (normally every cycle of the run loop). If you release it somewhere and then the autorelease pool tries to release it too, your program will crash. EITHER autorelease OR release for each time an object is retained.
nash
+4  A: 

You should autorelease the string before returning it. That's what the memory management rules say to do. If your app then crashes, that's evidence of a bug somewhere else in your code.

Chuck
A: 

does it work the same on the iPhone SDK ?

DJYod
Yes, manual (reference counting) memory management rules are the same on iPhone and OS X. Of course, Garbage Collection is available on OS X but not on the iPhone.
Barry Wark
FYI, if you want to add to your question, edit the question. The answer box is for answers, and this is not an answer.
Chuck