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字符串进行修改将会导致错误。