Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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;
}
like image 680
joshuapoehls Avatar asked Dec 21 '22 17:12

joshuapoehls


2 Answers

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.

like image 60
Fabian Kreiser Avatar answered Jan 05 '23 01:01

Fabian Kreiser


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...

like image 32
Kaelin Colclasure Avatar answered Jan 05 '23 00:01

Kaelin Colclasure