4

我正在尝试将一个NSString值从一个复制NSMutableArray到一个新变量中。NSString stringWithString正在返回NSString与我的数组中的对象具有相同内存地址的一个。为什么?

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

2 回答 2

7

1) 每当您使用@""语法创建字符串时,框架都会自动缓存该字符串。NSString是一个非常特殊的类,但框架会处理它。当您@"Some String"在应用程序的多个地方使用时,它们都将指向内存中的相同地址。只有当你使用类似的东西时-initWithData:encoding,字符串才会被缓存。

2)其他答案建议您应该-copy改用,但-copy如果对象是可变的,则只会创建对象的副本。(如 NSMutableString)
当您发送-copy到不可变对象(如 NSString)时,它与发送-retain返回对象本身相同。

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.

于 2012-08-09T19:57:13.580 回答
4

由于NSString实例是不可变的,因此该+stringWithString:方法只是返回具有递增引用计数的输入字符串。

如果您真的想强制创建一个新的相同字符串,请尝试:

NSString * copy = [NSString stringWithFormat:@"%@", [arr objectAtIndex:0]];

但是,这样做没有什么意义,除非您出于其他原因需要指针是唯一的......

于 2012-08-09T19:49:21.460 回答