开发者

When not to alloc and init an NSString

Whenever I need to create a new NSString variable I always alloc and init it. It seems that there are times when you don't want to do this. How do you know when to alloc a开发者_如何学Cnd init an NSString and when not to?


Whenever I need to create a new NSString variable I always alloc and init it.

No, that doesn't make sense.

The variable exists from the moment the program encounters the point where you declare it:

NSString *myString;

This variable is not an NSString. It is storage for a pointer to an NSString. That's what the * indicates: That this variable holds a pointer.

The NSString object exists only from the moment you create one:

[[NSString alloc] init];

and the pointer to that object is only in the variable from the moment you assign it there:

myString = [[NSString alloc] init];
//Or, initializing the variable in its declaration:
NSString *myString = [[NSString alloc] init];

Thus, if you're going to get a string object from somewhere else (e.g., substringWithRange:), you can skip creating a new, empty one, because you're just going to replace the pointer to the empty string with the pointer to the other one.

Sometimes you do want to create an empty string; for example, if you're going to obtain a bunch of strings one at a time (e.g., from an NSScanner) and want to concatenate some or all of them into one big string, you can create an empty mutable string (using alloc and init) and send it appendString: messages to do the concatenations.

You also need to release any object you create by alloc. This is one of the rules in the Memory Management Programming Guide.


If you want to initialise it to a known value, there is little point in using alloc, you can just use a string literal:

NSString* myStr = @"Some value";

If you want to initialise it with a format or whatever, but don't need it to stick around beyond the current autorelease pool lifetime, it's a bit neater to use the class convenience methods:

NSString* myTempStr = [NSString stringWithFormat:@"%d", myIntVar];

If you need its lifetime to go beyond that, either alloc/init or else add a retain to the previous call. I tend to slightly prefer the latter, but the two are pretty much equivalent. Either way you will need a balancing release later.

Note that, since NSString is not mutable, this sort of thing is not only unnecessary but actively wrong:

// don't do this!
NSString* myStr = [[NSString alloc] initWithString:@""];
myStr = someOtherStr;

since it leaks the initial placeholder value.


It seems that there are times when you don't want to do this.

I can't think of any time when I would want to alloc/init a NSString. Since NSStringgs are immutable, you pretty much always create new strings by one of:

  • convenience class method e.g.

    NSString* foo = [NSString stringWithFormat:...];
    
  • literal

    NSString* foo = @"literal";
    
  • NSString instance method

    NSString* foo = [bar uppercaseString];
    
  • copy from mutable string

    NSString* foo = [mutableBar copy];  // foo needs to be released or autoreleased in this case
    


I'm guessing that you are referring to using StringWithString or similar instead of initWithString? StringWithString alloc and inits for you under the hood and then returns an autoreleased string.

If you don't need to do any string manipulation other than to have the string, you can use NSString *str = @"string";

In general with iOS, the tighter you manage your memory the better. This means that if you don't need to return a string from a method, you should alloc init and then release it.

If you need to return a string, of course you'll need to return an autoreleased string. I don't think its any more complicated than that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜