尝试随机抛出不可变对象

时间:2011-08-30 18:35:19

标签: iphone objective-c memory-management nsmutablestring

程序的一部分从uitextfield获取文本,将其复制到可变字符串然后执行

     sharedManager.ce_name=name.text


    [sharedManager.ce_name replaceOccurrencesOfString:@" " withString:@"%20"
     options:NSLiteralSearch range:NSMakeRange(0, [sharedManager.ce_name length])];

此时它总是让我“尝试改变不可变对象” - 它不是随机的

我第一次收到此错误时将其更改为

    sharedManager.ce_name=(NSMutableString *)name.text

这个STILL让我试图改变不可变对象的错误,但它会随机发生 - 奇怪吧?

然后我将其改为

    NSMutableString *mutable_name = [NSMutableString stringWithString:name.text];

    sharedManager.ce_name=mutable_name;

我这样做还没有失败,但我确信我没有找到解决方案。

我的问题:

1)在第一次修复后它是否随意进行表明我有一些深层次的内存管理问题?

2)为什么C风格的演员没有修好它?

3)我目前的修复方法是否有效?

感谢您的时间:)

3 个答案:

答案 0 :(得分:4)

这里的问题是你使用强制转换的方式。当你转换指针时,它只是开始处理该位置的内存,就像它是表示该类型的数据块一样。

所以,如果我有一个指向Car类的指针:Car * mycar;,并将它转换为Person对象:(Person *)mycar;,程序将尝试访问那里的内存,就好像它是指着一个Person对象。然而,汽车不是一个人,除了旧的电视情景喜剧,所以当它试图访问这个或调用函数的成员时,它会尝试去一个包含其他东西而不是它期望的内存位置,并且未定义事情发生了(通常是崩溃)。

NSMutableString和NSString在这方面是不兼容的,因此从一个转换到另一个将导致可怕的时间。你的修复([NSMutableString stringWithString:])是正确的解决方案。

答案 1 :(得分:2)

  1. 如果它是随机执行的,则意味着name.text有时是一个可变字符串,有时候是一个不可变的字符串。

  2. 在这样的对象之间进行转换不会更改对象的类。它不会使你的不可变对象变得可变。

  3. “修复”可能是最好的方法(至少从我在你所展示的代码中看到的内容)

答案 2 :(得分:2)

至少没有看到所涉及的变量的声明,很难肯定地说,但是你的最终解决方案,创建一个新的可变字符串可能是正确的修复。至于你的问题,

  1. 本身不是内存管理,但它可能会覆盖它不应该存在的东西。
  2. 强制转换无法更改对象的基本类型。你(可能)有一个NSString,世界上所有的转换都无法进入NSMutableString。
  3. 就像我说的那样,但是我们需要看到更多的代码才能确定。这肯定是一个更好的解决方案。