【问题标题】:NSString immutable allows to change its values?NSString 不可变允许更改其值?
【发布时间】:2010-12-20 19:09:22
【问题描述】:

下面的代码编译并运行,但根据所有 iPhone 开发书籍和 Apple 文档,它不应该!有人可以向我解释一下不可变的 NSString 是如何在设置后允许更改其值的吗?我以为我必须使用 NSMuttableString 来更改同一个字符串变量的上下文?我正在使用 SDK 3.1。

NSString *test =[[NSString alloc] initWithString:@"TEST"];
[test release];
test = @"TEST2";

【问题讨论】:

    标签: objective-c nsstring immutability


    【解决方案1】:

    也许下面的示例将添加 Mark 和 Niels 的回复并帮助澄清事情。

    不可变字符串

    // Setup two variables to point to the same string
    NSString * str1 = @"Hello World";
    NSString * str2 = str1;
    
    // "Replace" the second string
    str2 = @"Hello ikilimnik";
    
    // And list their current values
    NSLog(@"str1 = %@, str2 = %@", str1, str2);
    

    可变字符串

    // Setup two variables to point to the same string
    NSMutableString * str1 = [NSMutableString stringWithString:@"Hello World"];
    NSMutableString * str2 = str1;
    
    // "Replace" the second string
    [str2 setString:@"Hello ikilimnik"];
    
    // And list their current values
    NSLog(@"str1 = %@, str2 = %@", str1, str2);
    

    请注意,当您使用不可变的 NSString 类时,“替换”字符串的唯一方法是创建一个新字符串并更新变量“str2”以指向它。然而,这不会影响“str1”所指向的内容,因此它仍然会引用原始字符串。

    在 NSMutableString 示例中,我们不创建第二个字符串,而是更改(改变)现有“Hello World”字符串的内容。由于两个变量继续指向同一个字符串对象,它们都会在调用 NSLog 时报告新值。

    区分指针变量和它指向的实际对象很重要。 NSString 对象是不可变的,但这并不能阻止您更改指向字符串的变量的值。

    数据类型“NSString *”是一个指向 NSString 对象的指针,而不是对象本身。如果您在 XCode 调试器中的任一 NSLog 语句处设置断点,您可能需要检查每个变量的原始值以澄清这一点。

    【讨论】:

    • 谢谢克里斯托弗,但是像这样的例子呢: NSString *str = @"one"; str = [str stringByAppendingString:@"two"];你是说即使我使用相同的变量,我正在创建两个不同的对象?另外,我们显式创建的这些 NSString 对象会发生什么,它们会被自动释放清理吗?
    • 是的,这将创建两个不可变的字符串对象。 “一”和“一”。可变字符串的好处之一是,如果您执行大量字符串附加样式操作(如您提供的示例),它们可以帮助避免额外的临时字符串对象。这可以提高速度和内存使用效率。
    • 关于那些先前的字符串对象(例如“one”)会发生什么,它们遵循标准的Objective-C内存管理规则,因此这取决于它们是如何创建的。在您的示例中,由于它们是应用程序源代码中的字符串常量,因此它们被稍微特殊对待,如果它们是通过编程方式创建的,它们可能会通过自动释放池进行处理,或者您可能需要明确地向它们发送释放消息。如果您有兴趣了解更多详细信息,请搜索“Cocoa 内存管理编程指南”文档。
    • 知道了,当我说 NSString *str = nil; 时 NSString 对象会发生什么会自动释放吗?
    【解决方案2】:

    您没有改变字符串,您只是重新分配变量 test 以指向不同的字符串。原始字符串没有被修改。

    【讨论】:

    • 好的,有道理。那么他们在 obj C 中改变字符串是什么意思呢?为什么在每本书中他们都说在为 NSString 分配新值时要创建新字符串?谢谢!
    • 它们的意思是更改字符串的单个字符,例如将“Hello,world!”更改为“Yello,world!”,方法是将第一个字符更改为“Y”,其余字符保持不变。这仅当字符串是可变的时才可能进行排序操作,例如在 C 中。
    【解决方案3】:

    TEST 和 TEST2 是 *test 指针指向的两个不同的字符串。

    您并没有更改第一行代码中显式分配的 NSString 对象的内容,而是将 *test 指向另一个对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-17
      • 2012-03-23
      • 1970-01-01
      • 2013-08-06
      • 2019-03-24
      • 1970-01-01
      • 2013-05-08
      • 2019-04-30
      相关资源
      最近更新 更多