【问题标题】:Usage of NSMutableString vs NSString?NSMutableString 与 NSString 的用法?
【发布时间】:2012-06-15 11:21:10
【问题描述】:

我对 NSStringNSMutable 字符串用法感到困惑。 假设我在类中声明了实例变量一和二:

NSString *one;
NSMutableString *two;

假设我已经使用属性创建了它们的 setter 和 getter。

假设我已经改变了我的“两个”字符串,如下所示:

     1. [two appendString:@"more string"];
     2. two = @"string"
     3. self.two = @"string"

问题:

  1. 第一行是否会释放先前的字符串并分配新对象并为其赋值。 如果是,那么这是否意味着在这种情况下创建 getter 和 setter 是不必要的?或者不必在NSMutablestring中创建属性

  2. 在这种情况下,之前分配的字符串对象会被释放吗?

  3. 当我们在这里调用 setter 时,肯定会释放第一个对象。这段代码是必要的还是我们可以使用代码行 2 来分配字符串。

现在关于NSString: 也可以像这样修改字符串:

    one = [one stringByAppendingString:@" more string"];
    self.one = [one stringByAppendingString:@" more string"];

使用 NSMutablestringNSString 哪个更好?

很抱歉发了很长的帖子,但我需要了解这些概念。

【问题讨论】:

    标签: iphone objective-c ios nsstring


    【解决方案1】:

    对于您问题的第一部分:

    1. 几乎肯定不是。我希望内存将被动态分配,而不是释放和重新分配。

    2. 如果前面的答案是否定的,这也是,否。

    3. 第二个和第三个选项甚至不适用于警告Incompatible pointer types assigning NSMutableString to NSString

    我预计NSMutableString 在内存方面的效率会稍高一些,因为您早先指出程序可能需要动态内存。 NSString 可能会被分配一个大小合适的内存块。

    您对NSMutableString 的看法似乎是NSString 的stringBy.. 方法会做的事情:

    使用NSString 及其stringBy... 方法,您可以创建新对象、释放旧对象(如果需要)并使新对象自动释放。 (如果您从非自动释放更改为自动释放,请注意,您的 dealloc 中可能有一个不再需要的释放)

    【讨论】:

    • 确实是一个非常好的洞察力。一个问题:如果我在 NSString 中使用 stringBy 方法并且内存由运行时本身管理,那么我是否需要为我的 NSString 创建属性?在这种情况下创建属性是不必要的任务吗?
    • 你打算制作什么属性?
    • stringBy... 方法返回的对象是自动释放的。如果您想拥有它们,请保留它们。是否对属性执行此操作取决于您,我想我可能会
    【解决方案2】:

    NSString 是一个不可变的字符串对象,这意味着,在初始化之后,你不能改变它,NSMutableString 是可变的,意味着你可以附加另一个字符串或其他修改。

    当您执行[two appendString:@"more string"] 时,指针仍然指向内存中的同一位置,您不必担心分配或解除分配。

    当您执行 two = @"string" 时,这意味着您将字符串指针指向内存中的特定位置,该位置包含内部值为“string”的静态字符串。

    当您执行self.two = @"string" 时,您已经声明了一个名为 two 的属性。通过在 xcode 中使用属性,您不必担心内存,因为您已经在属性声明中指定了。这是 xcode 提供给你的一个很好的工具,你绝对应该尽可能地使用它。

    【讨论】:

    • Otherwords: 使用 ARC 你可以同时使用 NSString 类并且不用担心,但是在某些时候,你应该使用更好的节省内存的地方(比如有很多动态字符串的动态单元格) NSMutableString.
    【解决方案3】:

    NSMutableString 将节省一些内存,因为NSString 对象始终是常量。因此,将新值重新分配给 NSString 变量将为新字符串分配新内存。

    但是,请注意您的代码中的一些错误。在向对象发送消息之前,您必须初始化对象:

    // this won't work
    NSString *one; 
    [one stringByAppendingString:@"more string"];
    
    // nor this
    NSMutableString *two;
    [two appendString:@"more string"];
    
    // first do this: 
    NSString *one = @"an initial string constant"; // or
    NSString *one = [NSString string]; 
    
    NSMutableString *two = [NSMutableString string]; 
    

    【讨论】:

    • 对此感到抱歉。但我跳过了那部分代码,因为我的问题与修改字符串有关,我认为我们可以假设那部分。
    【解决方案4】:

    NSString 对象是不可变的,这意味着当您“修改”NSString 时,您实际上是在创建一个新字符串,而不是修改旧字符串,这不是很有效。使用NSMutableString,字符串保存在缓冲区中,无法修改。

    所以简单的规则是,如果您需要以任何方式修改字符串,请使用NSMutableString,如果不是NSString。您也可以将NSMutableString 转换为NSString,但不能反过来(然后您需要复制)

    【讨论】:

    • 我明白。但我想了解内部工作,不想只学习规则而不了解它们的实际应用。不管怎样,谢谢!!
    • 如果NSMutableString 可以修改而NSString 不能修改,那你到底为什么要使用NSStringNSString 是否比 NSMutableString 有一些优势?
    【解决方案5】:

    NSMutableString 和 NSString 的区别在于:

    NSMutableString:NSMutableString 对象提供了修改它们所代表的底层字符数组的方法,而 NSString 没有。例如,NSMutableString 公开了 appendString、deleteCharactersInRange、insertString、replaceOccurencesWithString 等方法。所有这些方法都对存在于内存中的字符串进行操作。我们可以在运行时更改字符串对象的值。

    NSString:另一方面,如果你愿意,它只是一个创建一次然后只读的字符串;您会发现它的所有“操作”方法(子字符串、大写字符串等)都返回其他 NSString 对象,并且从未实际修改内存中的现有字符串。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-25
      • 2013-05-26
      • 1970-01-01
      • 2016-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多