区分copy和mutableCopy之前,先区分容器对象和非容器对象,很好理解
- 容器对象类似有:NSArray,NSMutableArray
- 非容器对象:NSString,NSMutableString
copy和mutableCopy在容器对象和非容器对象的处理上,有一定的区别。具体我们代码说事情:
对于非容器对象
NSString *str = @"test";
NSString *strCopy = [str copy];
NSString *strMCopy = [str mutableCopy];
NSLog(@"str 地址:%p——内容:%@", str, str);
NSLog(@"strCopy 地址:%p——内容:%@", strCopy, strCopy);
NSLog(@"strMCopy 地址:%p——内容:%@", strMCopy, strMCopy);
打印结果:
str 地址:0x10d593220——内容:test
strCopy 地址:0x10d593220——内容:test
strMCopy 地址:0x60000045e9c0——内容:test
可以看到,str copy出来的对象strCopy和str是指向同一个内存的。而string mutableCopy出来的对象strMCopy则指向新的内存地址。
NSMutableString *mString = [NSMutableString stringWithFormat:@"mutable string"];
NSString *stringCopy = [mString copy];
NSMutableString *mstringCopy = [mString copy];
NSMutableString *mstringMCopy = [mString mutableCopy];
NSLog(@"mString 地址:%p——内容:%@",mString,mString);
NSLog(@"stringCopy 地址:%p——内容:%@",stringCopy,stringCopy);
NSLog(@"mstringCopy 地址:%p——内容:%@",mstringCopy,mstringCopy);
NSLog(@"mstringMCopy 地址:%p——内容:%@",mstringMCopy,mstringMCopy);
[mstringCopy appendString:@"123"];
打印结果:
mString 地址:0x17007c0c0——内容:mutable string
stringCopy 地址:0x170038040——内容:mutable string
mstringCopy 地址:0x1700380a0——内容:mutable string
mstringMCopy 地址:0x17007c140——内容:mutable string
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to mutate immutable object with
以上四个都指向不同的内存。mstringCopy 的 copy 出来的对象,是immutable 的,所以会报错。从上面两个例子可以总结:对于系统的非容器对象来说,如果对一个非可变对象进行复制,则copy是指针复制(浅拷贝),mutableCopy则是对象复制(深拷贝);如果对一个可变对象来说,copy 和mstringCopy都是对象复制(深拷贝), 但是copy出来的对象,是immutable的。
对于容器对象
对于容器对象,整个对象的copy和mutableCopy的情况和非容器对象是一样的。
需要探讨的是容器内元素的情况。
�非可变对象
NSArray *arr = [NSArray arrayWithObjects:@"1",@"2",@"3", nil];
NSArray *arrCopy = [arr copy];
NSMutableArray *arrMCopy = [arr mutableCopy];
NSLog(@"arr 第一个元素的地址:%p",[arr objectAtIndex:0]);
NSLog(@"arrCopy 第一个元素的地址:%p",[arrCopy objectAtIndex:0]);
NSLog(@"arrMCopy 第一个元素的地址:%p",[arrMCopy objectAtIndex:0]);
打印结果:
arr 第一个元素的地址:0x1001043e0
arrCopy 第一个元素的地址:0x1001043e0
arrMCopy 第一个元素的地址:0x1001043e0
可变对象
NSMutableArray *marr = [NSMutableArray arrayWithObjects:@"a",@"b",@"c", nil];
NSArray *marrCopy = [marr copy];
NSMutableArray *marrMCopy = [marr mutableCopy];
NSLog(@"marr 第一个元素的地址:%p",[marr objectAtIndex:0]);
NSLog(@"marrCopy 第一个元素的地址:%p",[marrCopy objectAtIndex:0]);
NSLog(@"marrMCopy 第一个元素的地址:%p",[marrMCopy objectAtIndex:0]);
打印结果:
marr 第一个元素的地址:0x1001044a0
marrCopy 第一个元素的地址:0x1001044a0
marrMCopy 第一个元素的地址:0x1001044a0
可以看出,对于容器对象,容器元素的 copy 和 mutableCopy 都是指针复制(浅拷贝)。
总结
非容器对象、容器对象:
源对象类型 | 拷贝方式 | 副本对象类型 | 是否产生新对象 | 拷贝类型 |
---|---|---|---|---|
NS* | copy | NSArray | NO | 浅拷贝(指针拷贝) |
mutableCopy | NSMutableArray | YES | 深拷贝(对象拷贝) | |
NSMutable* | copy | NSArray | YES | 深拷贝(对象拷贝) |
mutableCopy | NSMutableArray | YES | 深拷贝(对象拷贝) |
容器对象中的某个元素:
容器对象某个元素 | 指针拷贝 |
---|
网友评论