views:

1263

answers:

6

As NSString strings are immutable, what is the value of the stringWithString: class method?

Update - yeah, I get the utility when used with NSMutableString, I just didn't see the utility with the NSString class. Also - I apologize if I wasn't clear enough; I wasn't intending to startup the initWithString vs stringWithString thread. Thanks for all the responses! Jeff

+4  A: 

As "Andy" points out in #318666, it's related to memory management, quoting:

The difference between initWithString and stringWithString is that stringWithString returns an auto-released pointer. This means that you don't need to release it specifically, since that will be taken care of next time that the auto-release pool cleans up any auto-released pointers.

initWithString, on the other hand, returns a pointer with a retain count of 1 - you do need to call release on that pointer, or else it would result in a memory leak.

(Taken from here)

Federico Builes
+1  A: 

Returns a string created by copying the characters from another given string

[NSString stringWithString:@"some string"]

It is equivalent to

[[[NSString alloc] initWithString:@"some string"] autorelease]
Alex
+1  A: 

Also, if you have a pointer to an NSString, it may actually be a subclass of NSString like NSMutableString. So, if you want to store the string and be guaranteed that it doesn't change, you should make a copy of it, hence stringWithString exists.

FigBug
Not sure this is quite valid - since, as you point out, NSMutableString is a subclass of NSString, you can actually have something like `NSString *string = @"str"; NSMutableString *mStr = [NSMutableString stringWithString:string];` and get a mutable string back.
Tim
@Tim: yes, that is valid.
newacct
I meant if you have a method like -(void) setName:(NSString *)name; you don't actually know if name is an NSString or a subclass. So, you may want to make a copy of it, so it's value doesn't change behind your back.
FigBug
+8  A: 

You might have a NSMutableString (or some home-grown NSString subclass) that you want to duplicate.

NSMutableString *buffer = [NSMutableString string];
// do something with buffer
NSString *immutableStringToKeepAround = [NSString stringWithString:buffer];

Of course, you can also just make a copy:

NSMutableString *buffer = [NSMutableString string];
// do something with buffer
NSString *immutableStringToKeepAround = [[buffer copy] autorelease];

but you own the copy and must release or autorelease it.

Don McCaughey
One minor distinction is that [[nil copy] autorelease] will return nil, but [NSString stringWithString:nil] will throw an exception.
Ahruman
Cool, I didn't know that! Handy information.
Don McCaughey
+1  A: 

As another use case, if (for whatever reason) you create your own subclass of NSString or NSMutableString, stringWithString: provides a handy way to instantiate it with an instance of either NSString, NSMutableString, or MyCustomString.

Peter Hosey
A: 

I often use +stringWithString: when I need to create an NSMutableString but start it with an initial value. For example:

NSMutableString * output = [NSMutableString stringWithString:@"<ul>"];
for (NSString * item in anArray) {
  [output appendFormat:@"<li>%@</li>", item];
}
[output appendString:@"</ul>"];
Dave DeLong