最近在看iOS关于深浅拷贝的知识,把自己的学习到的东西总结下,方便以后参考。下面开始:
深拷贝 ,alloc一个新的地址返回,为它赋值,
浅拷贝,并不创建新的内存空间,直接把原地址返回。
1.对于系统的非容器类对象
对于系统的非容器类对象,这里指的是NSString,NSNumber等等一类的对象。下面就以NSString来举例:
NSString *str = @"Christ_Beings";
NSString *strCopy = [str copy];
NSMutableString *mstrCopy = [str mutableCopy];
[mstrCopy appendString:@"的CSDN博客专栏"];
NSLog(@"%@",mstrCopy);
NSLog(@"%@",str);
NSLog(@"%@",strCopy);
运行的结果是:
Christ_Beings的CSDN博客专栏
Christ_Beings
Christ_Beings
由于,strCopy是浅拷贝,所以strCopy后面不能拼接字符串,否则XCode报错,如下图:
由此可见copy复制后的不可变对象的副本不可变。
下面看下对于对象MutableString的拷贝问题:
NSMutableString *mstr = [NSMutableString stringWithString:@"Christ_Beings"];
NSString *strCopy = [mstr copy];
NSMutableString *mstrCopy = [mstr copy];
NSMutableString *mstrMCopy = [mstr mutableCopy];
//[mstrCopy appendString:@"的CSDN博客专栏"]; //error
[mstr appendString:@"的CSDN博客专栏"];
[mstrMCopy appendString:@"http://blog.csdn.net/christ_beings/article/details/"];
NSLog(strCopy);
NSLog(mstr);
NSLog(mstrCopy);
NSLog(mstrMCopy);
[mstrCopy appendString:@"的CSDN博客专栏"]; //error 在这个地方程序会crash,原因是如果是对可变对象复制,都是深拷贝,但copy复制返回的对象是不可变的。注释此行,运行成功:Christ_Beings
Christ_Beings的CSDN博客专栏
Christ_Beings
Christ_Beingshttp://blog.csdn.net/christ_beings/article/details/
我们来下内存的情况如下图:
4个变量的内存均不一致,由此可知不论对于copy还是mutableCopy只要是对象是可变的都是深拷贝,但是对于copy来说,mstrCopy,它所指向的其实是一个imutable对象,是不可改变的,所以会出错。这点要注意,好好理解。
非容器类复制情况小结
只要是对象是可变的,其copy还是mutableCopy都是深拷贝,但是,对于copy来说,它所指向的其实是一个imutable对象,是不可改变的。对于对象是不可变的来说,copy是浅拷贝,mutableCopy是深拷贝,且mutableCopy后可以拼接字符串。
2.对于系统的容器类对象
比如NSDictionary,NSMutableDictionary,NSArray,NSMutableArray 等。对于容器类本身,上面讨论的结论也适用的,但是由于是容器类,容器类里面存储的是对象,下面探讨的是复制后容器内对象的变化。但首先要知道的是对于容器类,系统不仅会为该容器分配内存,也会为容器里面的对象分配内存。