views:

997

answers:

2

If I declare a pointer variable in this fashion:

NSString *foo;

And then somewhere later in my code do something such as:

foo = @"bar";

Is that ultimately taking my NSString, creating a new copy in memory with an additional string, then deleting my initial string? Would foo be better off as an NSMutableString?

+5  A: 

No. The @"bar" in your example is a string constant, and should be baked into your code. You don't need to worry about memory allocation / deallocation with this constant.

NSMutableString is more efficient to use when you are doing a lot of little manipulations to a string (appending substrings, etc.) and you don't want to keep allocating autoreleased NSStrings all over the place. I tend to avoid autoreleased strings on the iPhone if I can, due to memory concerns within loops.

Brad Larson
+9  A: 

No, foo is variable holding a pointer to an NSString. The assignment foo = @"bar" sets the value stored by the pointer foo to the address of the NSString @"bar". There is no copy made. If foo already pointed to an other NSString instance that was not a string constsant (i.e. like @"bar") and there are no other references to that instance, then you have a memory leak. You would

[foo release];
foo = @"bar";

in that case. You do not need to retain or release string constants like @"bar".

String constants cannot be mutated, so you will get a runtime error if you try to modify the value of a constant string. There's no difference between assigning @"bar" to an NSString* vs an NSMutableString*. Of course, you won't be able to use the mutating methods of the NSMutableString without a runtime error just because you assign the address of @"bar" (an NSString instance) to a variable of type NSMutableString*. If you want to mutate the string, you would do

NSMutableString *mutableFoo = [@"bar" mutableCopy];

In this case, a copy is obviously made and you are responsible for releasing mutableFoo when you're done with it.

Barry Wark
foo isn't a pointer; it's a variable holding a pointer. And the assignment doesn't change the value pointed to; that's what Coocoo thought it did, and it's wrong. The assignment replaces the pointer with a pointer to @"bar".
Peter Hosey
Also, there's no difference between assigning @"bar" to an NSString *variable vs. an NSMutableString *variable, period. No exceptions, and you'll get the runtime error from sending mutation messages to an immutable string no matter where you assigned the pointer.
Peter Hosey
I'll make the type of foo clearer. But assignment to foo does change the value of foo and the value assigned is the address of @"bar". If you think there is a clearer way to say that, please edit the post.
Barry Wark
Thanks for the review.
Barry Wark