对象复制copy与mutableCopy方法的区别

来源:互联网 发布:淘宝贷款app 编辑:程序博客网 时间:2024/05/21 21:42

NSObject类提供类copy和MutableCopy方法,通过这两个方法即可复制已有对象的副本。

copy与mutableCopy方法

copy方法用于复制对象的副本。通常来说,copy方法总是返回对象的不可修改的副本,即使该对象本身是可修改的。例如,如果程序调用NSMutableString的copy方法,将会返回不可修改的字符串对象。

mutableCopy方法用于复制对象的可变副本。通常来说,mubableCopy方法总是返回该对象可修改的副本,即使被复制对象本身不是可修改的,调用mutableCopy方法复制出来的副本也是可修改的。例如,程序调用NSString的mutableCopy方法,将会返回一个NSMutableString对象。

如论如何,copy和mutableCopy返回的总是原对象的副本,当程序对复制的副本进行修改时,原对象通常不会受到影响。

具体请看如下程序:

#import <Foundation/Foundation.h>int main(int argc, const char * argv[]){    @autoreleasepool {        NSMutableString* book = [NSMutableString stringWithString:@"疯狂iOS讲义"];        //复制book字符串的可变副本        NSMutableString* bookCopy = [book mutableCopy];        //修改副本,对原字符串没有任何影响        [bookCopy replaceCharactersInRange:NSMakeRange(2, 3) withString:@"Android"];        //此处可以看到原字符串的值没有改变        NSLog(@"book的值为:%@,book的值并没有改变",book);        //字符串副本的值发生了改变        NSLog(@"bookCopy的值为:%@,bookCopy的值发生了改变",bookCopy);                NSString* str = @"fkit";        NSMutableString* strCopy = [str mutableCopy];//1.        //向可变字符串strCopy追加字符串        [strCopy appendString:@".org"];        NSLog(@"strCopy的值为:%@",strCopy);                //调用book(可变字符串)的copy方法,程序返回一个不可修改的副本        NSMutableString* bookCopy2 = [book copy];//2.        //由于bookCopy2是不可修改的,因此下面的代码将会出现错误        [bookCopy2 appendString:@"aa"];        }    return 0;}

编译,运行该程序,可以看到如下输出:

2014-08-28 20:59:59.655 CopyTest[474:303] book的值为:疯狂iOS讲义,book的值并没有改变

2014-08-28 20:59:59.657 CopyTest[474:303] bookCopy的值为:疯狂Android讲义,bookCopy的值发生了改变

2014-08-28 20:59:59.657 CopyTest[474:303] strCopy的值为:fkit.org

2014-08-28 20:59:59.658 CopyTest[474:303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with appendString:'

*** First throw call stack:

(

0   CoreFoundation                      0x00007fff972f325c __exceptionPreprocess + 172

1   libobjc.A.dylib                     0x00007fff98044e75 objc_exception_throw + 43

2   CoreFoundation                      0x00007fff972f310c +[NSException raise:format:] + 204

3   CoreFoundation                      0x00007fff972c2dbe mutateError + 110

4   CopyTest                            0x0000000100000d91 main + 465

5   libdyld.dylib                       0x00007fff9299b5fd start + 1

6   ???                                 0x0000000000000001 0x0 + 1

)

libc++abi.dylib: terminating with uncaught exception of type NSException


从上面的程序可以看出,当程序复制对象的副本后,对副本所做对任何修改,对原始对象本身并没有任何影响。因此,程序可以看到book的值依然是“疯狂iOS讲义”,而bookCopy已经被改为“疯狂Android讲义”。

上面的程序中,1号粗体字代码复制类不可变字符串的可变副本,虽然被复制的str是不可变字符串,但是调用mutableCopy得到的依然是可变的副本。因此,程序可以对strCopy字符串进行修改。

2号粗体字代码复制了可变字符串的不可变副本,虽然被复制的book是可变字符串,但调用copy得到的依然是不可变的副本。因此,程序对博okCopy2字符串进行修改将会导致错误。

0 0