Reputation: 35237
I'm trying to copy an NSString
value out of an NSMutableArray
into a new variable. NSString stringWithString
is returning an NSString
with the same memory address as the object in my array. Why?
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
@autoreleasepool {
NSMutableArray *arr = [NSMutableArray arrayWithObject:@"first"];
NSLog(@"string is '%@' %p", [arr objectAtIndex:0], [arr objectAtIndex:0]);
// copy the string
NSString *copy = [NSString stringWithString:[arr objectAtIndex:0]];
NSLog(@"string is '%@' %p", copy, copy);
}
return 0;
}
Upvotes: 4
Views: 1865
Reputation: 8337
1) Whenever you're creating a string using the @""
syntax, the framework will automatically cache the string. NSString
is a very special class, but the framework will take care of it. When you use @"Some String"
in multiple places of your app, they will all point to the same address in memory. Only when you're using something like -initWithData:encoding
, the string won't be cached.
2) The other answers suggested that you should use -copy
instead, but -copy
will only create a copy of the object if the object is mutable. (like NSMutableString)
When you're sending -copy
to an immutable object (like NSString), it'll be the same as sending it -retain
which returns the object itself.
NSString *originalString = @"Some String";
NSString *copy = [originalString copy];
NSString *mutableCopy1 = [originalString mutableCopy];
NSString *mutableCopy2 = [mutableCopy copy];
NSString *anotherString = [[NSString alloc] initWithString:originalString];
--> originalString
, copy
, mutableCopy2
and anotherString
will all point to the same memory address, only mutableCopy1
points do a different region of memory.
Upvotes: 7
Reputation: 3975
Since NSString
instances are not mutable, the +stringWithString:
method is simply returning the input string with an incremented reference count.
If you really want to force the creating of a new, identical string, try:
NSString * copy = [NSString stringWithFormat:@"%@", [arr objectAtIndex:0]];
There is little point in doing so, though, unless you need the pointer to be unique for some other reason...
Upvotes: 4