Why is NSString stringWithString returning pointer to copied string?

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;
}

  • Can you manually implement Cocoa bindings?
  • How might I check if a particular NSString is present in an NSArray?
  • Xcode 4, Interface Builder and the Awareness of Classes in a Static Library
  • Playing a video stream on iOS7
  • How Can I Draw Image with Text Wrapping on iOS?
  • Objective-C Simplest way to create comma separated string from an array of objects
  • 2 Solutions Collect From Internet About “Why is NSString stringWithString returning pointer to copied string?”

    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.

    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…