0

程序的一部分从 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

这仍然让我尝试改变不可变对象错误,但它会随机发生 - 很奇怪吧?

然后我将其更改为

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

    sharedManager.ce_name=mutable_name;

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

我的问题:

1)在第一次修复之后它随机执行的事实是否表明我有一些根深蒂固的内存管理问题?

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

3) 我目前的修复工作会起作用吗?

谢谢你的时间 :)

4

3 回答 3

4

这里的问题是您使用铸造的方式。当您转换一个指针时,它只是开始将该位置的内存视为表示该类型的数据块。

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

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

于 2011-08-30T18:51:58.540 回答
2
  1. 如果它是随机执行的,则意味着 name.text 有时是可变字符串,有时是不可变字符串。

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

  3. 该“修复”可能是最好的方法(至少从我在您显示的代码中可以看到)

于 2011-08-30T18:43:14.133 回答
2

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

  1. 本身不是内存管理,但它可能正在覆盖它不应该在某处拥有的东西。
  2. 强制转换不能改变对象的基本类型。你(大概)有一个 NSString 并且世界上所有的演员都不能把它变成一个 NSMutableString。
  3. 就像我说的,可能,但我们需要查看更多代码来确定。这当然是一个更好的解决方案。
于 2011-08-30T18:44:20.210 回答