views:

113

answers:

4

What's the difference between NSString *myString = @"Johnny Appleseed" versus NSString *myString = [NSString stringWithString: @"Johnny Appleseed"]?

Where's a good case to use either one?

+3  A: 

In the first case, you are getting a pointer to a constant NSString. As long as your program runs, myString will be a valid pointer. In the second, you are creating an autoreleased NSString object with a constant string as a template. In that case, myString won't point to a real object anymore after the current run loop ends.

Edit: As many people have noted, the normal implementation of stringWithString: just returns a pointer to the constant string, so under normal circumstances, your two examples are exactly the same. There is a bit of a subtle difference in that Objective-C allows methods of a class to be replaced using categories and allows whole classes to be replaced with class_poseAs. In those cases, you might run into a non-default implementation of stringWithString:, which may have different semantics than you expect it to. Just because it happens to be that the default implementation does the same thing as a simple assignment doesn't mean that you should rely on subtle implementation-specific behaviour in your program - use the right case for the particular job you're trying to do.

Carl Norum
-1 Have you tried this? I think you'll find that stringWithString: with a constant string parameter just returns the constant string.
JeremyP
@JeremyP, if you look at the discussion under @quixoto's answer below, there is some more explanation of what I was getting at. I guess I should edit this one for clarity.
Carl Norum
A: 

In practice, nothing. You wouldn't ever use the second form, really, unless you had some special reason to. And I can't think of any right now.

(See Carl's answer for the technical difference.)

quixoto
In practice there is a definite difference in the lifetime of each object, and when `myString` points to a real object and when it doesn't.
Carl Norum
@carl: They both produce the same pointer value. No difference in the lifetime as both point to the exact same data in memory.
jojaba
@jojaba - potentially not if there's a class posing as `NSString` or someone has overriden `stringWithString` in a category - seems dangerous to make assumptions like that.
Carl Norum
Not really. For a constant string `x` `[NSString stringWithString: x]` is equivalent to `[[x retain] autorelease]`. And for string literals `retain` and `autorelease` do nothing. If you don’t believe me try this: `NSAssert( @"a" == [NSString stringWithString: @"a"], @"Ok, Sven was wrong" )`.
Sven
@carl Sure, but that is not what he asked. He asked the differences between the two statements. And beside, you can pose as different type in his first example too.
jojaba
@jojaba, exactly. I guess the difference *really* comes down to that there is a method called in one case and not in the other. Maybe that's a better way for me to have explained it.
Carl Norum
+5  A: 

The other answers here are correct. A case where you would use +stringWithString: is to obtain an immutable copy of a string which might be mutable.

David M.
+2  A: 

Other than syntax and a very very minor difference in performance, nothing. The both produce the exact same pointer to the exact same object.

Use the first example. It's easier to read.

jojaba