copy

1) 对于非容器类对象如NSString, NSNumber之类的而言

NSString *str1 = @"abc";
NSString *str2 = [str1 copy]; // 地址和Str1一样
NSString *str3 = [str1 mutableCopy]; // 地址和str1不同, 虽然是深拷贝,但无法修改str3内容(语法不通过)
NSMutableString *str4 = [str1 copy]; // 地址和Str一样, 修改Str4会崩溃
NSMutableString *str5 = [str1 mutableCopy]; // 地址和str1 不同

NSLog(@"str1 ===== %p", str1);
NSLog(@"str2 ===== %p", str2);
NSLog(@"str3 ===== %p", str3);
NSLog(@"str4 ===== %p", str4);
NSLog(@"str5 ===== %p", str5);

[str3 appendString:@"xxx"]; // 报错,语法错误
[str4 appendString:@"xxx"]; // 会导致程序崩溃. reason: ‘Attempt to mutate immutable object with appendString:‘

执行结果:

2015-09-13 22:08:58.958 test[8507:69904] str1 ===== 0x105b407d0

2015-09-13 22:08:58.959 test[8507:69904] str2 ===== 0x105b407d0

2015-09-13 22:08:58.959 test[8507:69904] str3 ===== 0x7fdfc042b150

2015-09-13 22:08:58.959 test[8507:69904] str4 ===== 0x105b407d0

2015-09-13 22:08:58.959 test[8507:69904] str5 ===== 0x7fdfc042ca60

// =============================================

   NSMutableString *str1 = [NSMutableString stringWithFormat:@"abc"];
    NSString *str2 = [str1 copy]; // 地址和Str1不同
    NSString *str3 = [str1 mutableCopy]; // 地址和str1不同, 虽然是深拷贝,但无法修改str3内容(语法不通过)
    NSMutableString *str4 = [str1 copy]; // 地址和Str1不同, str4本质是NSString而不是NSMutableString, 修改Str4会崩溃
    NSMutableString *str5 = [str1 mutableCopy]; // 地址和str1 不同

    NSLog(@"str1 ===== %p", str1);
    NSLog(@"str2 ===== %p", str2);
    NSLog(@"str3 ===== %p", str3);
    NSLog(@"str4 ===== %p", str4);
    NSLog(@"str5 ===== %p", str5);

执行结果:

2015-09-13 22:55:32.116 test[11538:104525] str1 ===== 0x7fab3949b140

2015-09-13 22:55:32.117 test[11538:104525] str2 ===== 0x7fab3949e5d0

2015-09-13 22:55:32.117 test[11538:104525] str3 ===== 0x7fab39490970

2015-09-13 22:55:32.117 test[11538:104525] str4 ===== 0x7fab394975a0

2015-09-13 22:55:32.117 test[11538:104525] str5 ===== 0x7fab3949e470

结论: 对于可变类型的拷贝(copy/mutableCopy)都是深拷贝, 但使用copy返回的对象的真实类型是不可变的, 修改它会导致程序崩溃; 对于不可变类型的copy是浅拷贝, mutableCopy是深拷贝.

2) 对于容器类对象如NSArray,  NSDictionary之类的而言

NSArray *array1 = [NSArray arrayWithObjects:[NSMutableString stringWithFormat:@"a"], @"b", @"c", nil];
NSArray *array2 = [array1 copy]; // 地址与array1一样
NSArray *array3 = [array1 mutableCopy]; // 地址与array1不同
NSMutableArray *array4 = [array1 copy]; // 地址与array1一样

NSMutableArray *array5 = [array1 mutableCopy]; // 地址与array1不样

NSArray *array6 = [[NSArray alloc] initWithArray:array1 copyItems:YES]; // 地址与array1不同, 容器内的可变元素深拷贝, 而不可变元素依然是浅拷贝.

NSArray *array7 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array1]]; // 地址与array1不同, 容器内的元素都进行深拷贝

NSMutableString *str = array5[0];

[str appendString:@"xxx"];

NSMutableString *str2 = array5[1];

// [str2 appendString:@"xxx"]; // 会导致程序崩溃.

NSLog(@"array1 ==== %p", array1);

NSLog(@"array2 ==== %p", array2);

NSLog(@"array3 ==== %p", array3);

NSLog(@"array4 ==== %p", array4);

NSLog(@"array5 ==== %p", array5);

NSLog(@"array6 ==== %p", array6);

NSLog(@"array7 ==== %p", array7);

NSLog(@"array1[0] ==== %p", array1[0]);

NSLog(@"array2[0] ==== %p", array2[0]);

NSLog(@"array3[0] ==== %p", array3[0]);

NSLog(@"array4[0] ==== %p", array4[0]);

NSLog(@"array5[0] ==== %p", array5[0]);

NSLog(@"array6[0] ==== %p", array6[0]);

NSLog(@"array7[0] ==== %p", array7[0]);

NSLog(@"array1[1] ==== %p", array1[1]);

NSLog(@"array2[1] ==== %p", array2[1]);

NSLog(@"array3[1] ==== %p", array3[1]);

NSLog(@"array4[1] ==== %p", array4[1]);

NSLog(@"array5[1] ==== %p", array5[1]);

NSLog(@"array6[1] ==== %p", array6[1]);

NSLog(@"array7[1] ==== %p", array7[1]);

NSLog(@"array1[0] ==== %@", array1[0]);

NSLog(@"array2[0] ==== %@", array2[0]);

NSLog(@"array3[0] ==== %@", array3[0]);

NSLog(@"array4[0] ==== %@", array4[0]);

NSLog(@"array5[0] ==== %@", array5[0]);

NSLog(@"array6[0] ==== %@", array6[0]);

NSLog(@"array7[0] ==== %@", array7[0]);

执行结果:

2015-09-13 23:15:46.235 test[12791:118074] array1 ==== 0x7fc6e1d1dab0

2015-09-13 23:15:46.236 test[12791:118074] array2 ==== 0x7fc6e1d1dab0

2015-09-13 23:15:46.236 test[12791:118074] array3 ==== 0x7fc6e1d2ef40

2015-09-13 23:15:46.236 test[12791:118074] array4 ==== 0x7fc6e1d1dab0

2015-09-13 23:15:46.236 test[12791:118074] array5 ==== 0x7fc6e1d19430

2015-09-13 23:15:46.236 test[12791:118074] array6 ==== 0x7fc6e1d2fc60

2015-09-13 23:15:46.236 test[12791:118074] array7 ==== 0x7fc6e1c30cd0

2015-09-13 23:15:46.237 test[12791:118074] array1[0] ==== 0x7fc6e1d1ba10

2015-09-13 23:15:46.237 test[12791:118074] array2[0] ==== 0x7fc6e1d1ba10

2015-09-13 23:15:46.237 test[12791:118074] array3[0] ==== 0x7fc6e1d1ba10

2015-09-13 23:15:46.237 test[12791:118074] array4[0] ==== 0x7fc6e1d1ba10

2015-09-13 23:15:46.237 test[12791:118074] array5[0] ==== 0x7fc6e1d1ba10

2015-09-13 23:15:46.237 test[12791:118074] array6[0] ==== 0x7fc6e1d2fc40

2015-09-13 23:15:46.238 test[12791:118074] array7[0] ==== 0x7fc6e1c2faf0

2015-09-13 23:15:46.238 test[12791:118074] array1[1] ==== 0x10fd197f0

2015-09-13 23:15:46.238 test[12791:118074] array2[1] ==== 0x10fd197f0

2015-09-13 23:15:46.238 test[12791:118074] array3[1] ==== 0x10fd197f0

2015-09-13 23:15:46.238 test[12791:118074] array4[1] ==== 0x10fd197f0

2015-09-13 23:15:46.239 test[12791:118074] array5[1] ==== 0x10fd197f0

2015-09-13 23:15:46.239 test[12791:118074] array6[1] ==== 0x10fd197f0

2015-09-13 23:15:46.239 test[12791:118074] array7[1] ==== 0x7fc6e1c2fc50

2015-09-13 23:15:46.239 test[12791:118074] array1[0] ==== axxx

2015-09-13 23:15:46.239 test[12791:118074] array2[0] ==== axxx

2015-09-13 23:15:46.239 test[12791:118074] array3[0] ==== axxx

2015-09-13 23:15:46.240 test[12791:118074] array4[0] ==== axxx

2015-09-13 23:15:46.240 test[12791:118074] array5[0] ==== axxx

2015-09-13 23:15:46.240 test[12791:118074] array6[0] ==== a

2015-09-13 23:15:46.240 test[12791:118074] array7[0] ==== a

结论: 对于非容器类对象的结论同样适用于容器类对象, 只是容器类对象内的元素始终都只是浅拷贝.  若要对容器内的元素也进行真正意义上的深拷贝, 可以采用归档解档的方式进行.

官方相关链接:https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html

时间: 2024-08-05 03:59:51

copy的相关文章

使用Second Copy同步ftp服务器的差异文件

公司一直用自主开发的一个同步工具来进行数据库文件异机备份的,但无奈太不稳定,三天两头出现服务挂死的问题,特别是最近这1个月,几天就1次. 问题现象都是服务一直在运行,但没有复制文件到备份机上,而且备份服务重启需要2个小时到2天…… 原因估计是网络问题导致文件共享复制中断,无法结束正在复制文件的这个进程而引起的.具体原因不想深究,那是个无底洞. 所以前天开始,就开始在各大软件网站和论坛中,搜索满足需求的同步软件,要求如下: 软件安装在客户端,通过ftp服务,定期从服务器上下载差异文件 支持设置执行

angular.copy和angular.extend

angular.copy用于深复制,而angular.extend用于拓展.     angular.copy(src,[dst]) src:源对象 dst:目标对象,复制的对象 js中 '= '操作符复制的是指针,所以前后两个变量指向的还是内存中的同一个对象,所以在其中一个变量上操作该对象时,对另外一个变量也会生效.而angular.copy方法是深复制,会在内存中再生成一个对象,两个变量彼此独立,互不影响. 接收一个必须参数src,一个可选参数dst.如果dst没有提供,就会创建对象或者数组

assign,copy,strong,weak,nonatomic的具体理解

例子: NSString *houseOfMM = [[NSString alloc] initWithString:'MM的三室两厅']; 上面一段代码会执行以下两个动作:  1 在堆上分配一段内存用来存储@' MM的三室两厅 ' ,比如:内存地址为 0X1111  内容为 ' MM的三室两厅' ,  2 在栈上分配一段内存用来存储 houseForWife ,比如:地址为 0XAAAA  内容自然为 0X1111 下面分别看下(assign,retain,copy):  1.assign的情

assign, retain, weak, strong, copy,unsafe_unretain

readonly, readwrite:是控制属性的访问权限,readonly只生成getter方法,其他类是无法修改其值的.readwrite是会同时生成getter和setter方法,其他类可以修改其值. assign, retain, weak, strong, copy,unsafe_unretained:在non-ARC中,assign和retain是一组,assign的对象属性引用计数不变,而retain会被+1.对应的在ARC中,weak和strong是一组,weak的对象属性引用

python copy

import copya = [1, 2, 3, 4, ['a', 'b']]  #原始对象b = a  #赋值,传对象的引用c = copy.copy(a)  #对象拷贝,浅拷贝d = copy.deepcopy(a)  #对象拷贝,深拷贝a.append(5)  #修改对象aprint a [1, 2, 3, 4, ['a', 'b'], 5] >>> print b [1, 2, 3, 4, ['a', 'b'], 5] >>> print c [1, 2, 3,

copy, retain, assign , readonly , readwrite,strong,weak,nonatomic整理

copy:建立一个索引计数为1的对象,然后释放旧对象 对NSString对NSString 它指出,在赋值时使用传入值的一份拷贝.拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效.更深入的讨论,请参考“复制”部分. retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1对其他NSObject和其子类对参数进行release旧值,再retain新值指定retain会在赋值时唤醒传入值的retain消息.此属性只能用于Objective

如果将synthesize省略,语义特性声明为assign retain copy时,自己实现setter和getter方法

如果将synthesize省略,并且我们自己实现setter和getter方法时,系统就不会生成对应的setter和getter方法,还有实例变量 1,当把语义特性声明为assign时,setter和getter时方法内部实现 - (void)setName:(NSString *)name{ _name = name; } - (NSString *)name{ return _name; } 2,当把语义特性声明为retain时,setter和getter方法内部实现 - (void)set

svn: is already a working copy for a different url 解决办法

svnX    svn: E155000: '/Users/mac/Desktop/SHiosProject/SVNmangerfiles/wuye'   is already a working copy for a different URL 首先说明下原因: 出现这种情况大多是由于原有的目录是使用svn更新的,并且指定了一个更新的url,比如说 http://192.168.10.1/svn/xxx,如果此url由于某种原因无法使用,而换成了http://192.168.10.2/svn/

ansible之copy模块

有时需要把某个文件批量拷贝到其他主机上,那么ansible已经提供相应的模块了.那就是copy.. copy用法 [[email protected] ~]# ansible-doc -s copy less 436 Copyright (C) 1984-2009 Mark Nudelman less comes with NO WARRANTY, to the extent permitted by law. For information about the terms of redistr

IOS开发之copy的问题

copy的目的就是修改副本,修改原始对象和副本时不会产生干扰. 定义一个不可变属性A,再定义一个可变属性B.用B做添加删除等操作后再将B赋值给A时,有些人习惯用A = B:其实这样是不安全的. 假设有下面的一段代码: ? 1 2 3 4 5 6 7 8 9 10   int main() {    NSMutableString *strM = [NSMutableString [email protected]"123"];    NSString *str = strM;    N