天天看点

因copy和mutableCopy与 强制类型转换,使用不当而产生的异常

导致出现错误的代码:

先说一下执行了那些代码才出现这样的错误的:

定义了这样一个 NSString 的对象:

NSString *resultString = nil;
           

然后 用 resultString 调用了一个方法:

需要说明的是,insertComma 这个方法,是一个 NSMutableString 类的扩展方法。把 resultString 强制转换成 NSMutableString 类型,才能 调用 insertComma 这个方法。

insertComma 这方法 如下:

#import "NSMutableString+Deletion.h"

@implementation NSMutableString (Deletion)

- (void)insertComma {
    int count = ;
    long long int a = self.longLongValue;
    while (a != )    {
        count++;
        a /= ;
    }
    NSMutableString *newstring = [NSMutableString string];
    while (count > ) {
        count -= ;
        NSRange rang = NSMakeRange(self.length - , );
        NSString *str = [self substringWithRange:rang];
        [newstring insertString:str atIndex:];
        [newstring insertString:@"," atIndex:];
        [self deleteCharactersInRange:rang];
    }
    [newstring insertString:self atIndex:];
    [self setString:newstring];

} // insertComma
           

然而,编译程序,一执行,就出现了错误:

控制台打印出来的错误:

控制台打印出来的错误:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'
           

图片 如下:

因copy和mutableCopy与 强制类型转换,使用不当而产生的异常

解决办法:

后来,我把 resultString 调用 insertComma 方法的代码,改成这样就没有错误了,编译器就完美通过啦。

NSMutableString *strResult = [resultString mutableCopy];
[strResult insertComma];
resultString = [strResult copy];
           

那么为什么会这样呢?

我的猜想:

我觉得,在

[(NSMutableString *)resultString insertComma];

这行代码中,

resultString

在转换成

(NSMutableString *)

类型时,默认使用的是 copy 这个方法,而不是 mutableCopy 。也就是说

(NSMutableString *)resultString

默认转换成的是 NSString * 不可变的字符串对象。

补充:

copy 与 mutableCopy 这两个方法的区别是:

1、copy 这个方法是要 拷贝出一 个 不可变的 副本,不改变原始对象的可变性;

2、mutableCopy 这个方法是要拷贝出一个 可变的 副本,不改变原始对象的可变性。

如 :

NSMutableString *strResult = [resultString mutableCopy];
[strResult insertComma];
resultString = [strResult copy];
           

意思是 不可变的 resultString 拷贝出来一个 可变的 strResult ,然后,用 可变的 strResult 去调用 insertComma 方法,最后,可变的 strResult 拷贝出来一个 不可变的 对象,并把它 赋值 给 resultString 。

关于更多 copy 与 mutableCopy 的区别,请参考:

这里写链接内容

http://blog.csdn.net/fg313071405/article/details/16858787

http://www.cnblogs.com/foxmin/archive/2012/07/05/2577154.html