【问题标题】:Why is NSString stringWithString returning pointer to copied string?为什么 NSString stringWithString 返回指向复制字符串的指针?
【发布时间】:2012-08-09 19:44:15
【问题描述】:

我正在尝试将 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;
}

【问题讨论】:

  • 不知道为什么会这样,但你试过NSString *copy = [[arr objectAtIndex:0] copy];
  • 我有,结果一样——内存地址匹配。
  • 我需要这样做的原因是因为在我的真实应用程序中,数组作为参数传递给我的方法,稍后将被处理。当它被处理时,我丢失了我的 NSString,即使我已经从数组中“复制”了它。
  • 那么NSString * str = [NSString stringWithCString:[[arr objectAtIndex:0] UTF8String] encoding:NSUTF8StringEncoding];
  • @silent__thought:如果这是你真正的问题,那么问题在于你用来“复制”字符串的方法并没有授予你对结果的所有权。 stringWithString: 返回一个无主对象。使用 copyalloc/initWithString: 获取拥有的版本。指针还是一样的,但是引用计数是正确的并且对象会存活。

标签: objective-c nsstring


【解决方案1】:

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

--> originalStringcopymutableCopy2anotherString 都会指向同一个内存地址,只有 mutableCopy1 指向不同的内存区域。

【讨论】:

  • @Fabain 如果是这种情况,那么如果我们对 *copy 变量的值进行任何更改,为什么此更改不会反映在 *originalString 值上。
  • @i_Intiution 您不能对不可变对象进行更改。
【解决方案2】:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-27
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-19
    • 2020-04-11
    相关资源
    最近更新 更多