[解析]Objective-C 深浅拷贝
来源:互联网 发布:亚马逊和淘宝哪个大 编辑:程序博客网 时间:2024/04/25 16:43
在C++中,深浅拷贝的区别如下:
- 浅拷贝。
缺省拷贝构造函数在拷贝过程中是按字节复制的,对于指针型成员变量只复制指针本身,而不复制指针所指向的目标,也就是两个对象中成员指针变量指向同一块内存
- 深拷贝。对一个对象进行深拷贝,系统会为新对象变量中得每一个对象成员分配空间,并将原对象成员内容赋值给新对象对应的成员变量。
在iOS中,由于Objective-C自身提供了copy函数,但是深浅难辨,因此做下总结:
- 非容器变量(immutable对象与mutable对象的区分)
如下代码所示,可以得出结论,对于一个immutable对象,进行copy得到的对象是浅拷贝,进行mutableCopy得到的对象是深拷贝
NSString *string = @"animal"; NSString *stringCopy11 = [string copy]; NSMutableString *stringMutableCopy11 = [string mutableCopy]; NSString *stringCopy12 = [string mutableCopy];//非法,容易错误操作 NSMutableString *stringMutableCopy12 = [string copy];//非法,容易错误操作 NSLog(@"%p \n%p \n%p \n%p \n%p", string, stringCopy11, stringCopy12, stringMutableCopy11, stringMutableCopy12); //output /* 2015-09-30 21:38:50.665 HelloWorld[966:49309] 0x10a0560a8 0x10a0560a8 0x7fd2f049eb00 0x7fd2f049ce90 0x10a0560a8 */
如下代码所示,可以得出结论,对于一个mutable对象,不管进行copy或mutableCopy得到的对象都是深拷贝
NSMutableString *mutableString1 = [[NSMutableString alloc] initWithString:@"animal"]; NSString *stringCopy21 = [mutableString1 copy]; NSMutableString *stringMutableCopy21 = [mutableString1 mutableCopy]; NSMutableString *stringCopy22 = [mutableString1 copy];//非法,容易错误操作 NSString *stringMutableCopy22 = [mutableString1 mutableCopy];//非法,容易错误操作 NSLog(@"%p \n%p \n%p \n%p \n%p", mutableString1, stringCopy21, stringCopy22, stringMutableCopy21, stringMutableCopy22); //output /* 2015-09-30 21:38:50.665 HelloWorld[966:49309] 0x7fd2f049d8c0 0x7fd2f049d920 0x7fd2f049e430 0x7fd2f049d940 0x7fd2f049e450 */
- 容器变量
- 由以下实验可以看出,容器变量与非容器变量在进行copy与mutableCopy时的情况是一致的,关键在于容器变量如array中得对象都是浅拷贝,其都指向对应的同一块内存
- trueDeepCopy31、trueDeepCopy33并不是真正意义上的深拷贝,其效果还是同前面讨论的一样并不是真正意义上得深拷贝,而trueDeepCopy32才算的上时真正意义上的深拷贝,因为其对象地址、对象成员地址都都与原来的对象不同。
NSArray *a1 = @[@"dog", @"cat"]; NSArray *a2 = @[@"tiger", @"lion"]; NSArray *a3 = @[@"cow", @"sheep"]; NSArray *array = @[a1, a2, a3]; NSArray *arrayCopy11 = [array copy]; NSArray *arrayCopy12 = [array mutableCopy]; NSMutableArray *arrayMutableCopy11 = [array mutableCopy]; NSMutableArray *arrayMutableCopy12 = [array copy]; NSLog(@"%p %p %p \n%p %p %p\n%p %p %p\n%p %p %p\n%p %p %p", array, array[0], array[0][0], arrayCopy11, arrayCopy11[0], arrayCopy11[0][0], arrayCopy12, arrayCopy12[0], arrayCopy12[0][0], arrayMutableCopy11, arrayMutableCopy11[0], arrayMutableCopy11[0][0], arrayMutableCopy12, arrayMutableCopy12[0], arrayMutableCopy12[0][0]);//output /* 2015-09-30 22:09:07.284 HelloWorld[1284:60191] 0x7fa2ab52fd80 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52fd80 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52fc20 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52f010 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52fd80 0x7fa2ab52ffb0 0x10b0bc0b8 */ NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithArray:array]; NSArray *arrayCopy21 = [array copy]; NSArray *arrayCopy22 = [array mutableCopy]; NSMutableArray *arrayMutableCopy21 = [array mutableCopy]; NSMutableArray *arrayMutableCopy22 = [array copy]; NSLog(@"%p %p %p \n%p %p %p\n%p %p %p\n%p %p %p\n%p %p %p", mutableArray, mutableArray[0], mutableArray[0][0], arrayCopy21, arrayCopy21[0], arrayCopy21[0][0], arrayCopy22, arrayCopy22[0], arrayCopy22[0][0], arrayMutableCopy21, arrayMutableCopy21[0], arrayMutableCopy21[0][0], arrayMutableCopy22, arrayMutableCopy22[0], arrayMutableCopy22[0][0]); //output /* 2015-09-30 22:09:07.284 HelloWorld[1284:60191] 0x7fa2ab52f060 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52fd80 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52f0b0 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52f100 0x7fa2ab52ffb0 0x10b0bc0b8 0x7fa2ab52fd80 0x7fa2ab52ffb0 0x10b0bc0b8 */ NSArray *trueDeepCopy31 = [[NSArray alloc] initWithArray:array copyItems:YES]; NSArray *trueDeepCopy32 = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]]; NSMutableArray *trueDeepCopy33 = [[NSMutableArray alloc] initWithArray:array copyItems:YES]; NSLog(@"%p %p %p \n%p %p %p\n%p %p %p", trueDeepCopy31, trueDeepCopy31[0], trueDeepCopy31[0][0], trueDeepCopy32, trueDeepCopy32[0], trueDeepCopy32[0][0], trueDeepCopy33, trueDeepCopy33[0], trueDeepCopy33[0][0]); //output /* 2015-09-30 23:13:18.877 HelloWorld[637:12672] 0x7fe7414a8d90 0x7fe7414a9f00 0x10a5050b8 0x7fe7414a96a0 0x7fe7414a9f00 0x10a5050b8 0x7fe7414a9770 0x7fe7414a9f00 0x10a5050b8 0x7fe7414aa070 0x7fe7414a9f00 0x10a5050b8 0x7fe7414a96a0 0x7fe7414a9f00 0x10a5050b8 2015-09-30 23:13:18.877 HelloWorld[637:12672] 0x7fe7414aa0c0 0x7fe7414a9f00 0x10a5050b8 0x7fe7414aaed0 0x7fe7414aab80 0x7fe7414aab20 0x7fe7414aaae0 0x7fe7414a9f00 0x10a5050b8 */
- 自定义拷贝
自定义拷贝需要继承NSCopying、NSMutableCopying协议,重写以下两个方法。
- (id)copyWithZone:(NSZone *)zone;- (id)mutableCopyWithZone:(NSZone *)zone;
//示例//FSJAnimal.h@interface FSJAnimal : NSObject@property(nonatomic, copy) NSString *name;@property(nonatomic, strong) NSSet *families;-(id)initWithName:(NSString *)name;@end//FSJAnimal.m@interface FSJAnimal()<NSCopying, NSMutableCopying> @end@implementation FSJAnimal@synthesize name;@synthesize families;//懒初始化-(NSSet*)families{ return [_internalFamilies copy];} -(id)initWithName:(NSString *)name{ if(self = [super init]) { _name = name; _internalFamilies = [[NSMutableSet alloc] init]; } return self;}- (id)copyWithZone:(NSZone *)zone{ FSJAnimal *copy = [[[self class] alloc] init]; copy->name = [name copy]; copy->families = [families copy]; return copy;}- (id)mutableCopyWithZone:(NSZone *)zone{ FSJAnimal *copy = [[[self class] alloc] init]; copy->name = [name mutableCopy]; copy->families = [families mutableCopy]; return copy;}@end
0 0
- [解析]Objective-C 深浅拷贝
- Objective-c 深浅拷贝
- Objective-C 深浅拷贝学习
- 浅析Objective-C 深浅拷贝
- ios&object-c深浅拷贝解析
- ios学习路线—Objective-C(深浅拷贝)
- 深浅拷贝解析
- 【C++】 浅析深浅拷贝
- C++String深浅拷贝
- C++String深浅拷贝问题
- c++-----string和深浅拷贝
- Objective-C -深浅复制
- Objective-C -深浅复制
- Objective-C -深浅复制
- iOS开发中表视图搜索栏实现中的Objective-C 深浅拷贝问题
- iOS开发中表视图搜索栏实现中的Objective-C深浅拷贝问题
- C++String深浅拷贝、写时拷贝
- 深浅拷贝
- html编程tips
- mysql以及oracle的递归查询
- phalapi-入门篇4(国际化高可用和自动生成文档)
- MFC Toolbar图标尺寸调整出错解决方法
- 操作系统和网络面试总结
- [解析]Objective-C 深浅拷贝
- ACM学习-破坏行动-最大网络流
- iOS软件开发 内存管理之拷贝
- C#学习之路,学习笔记 2.1 整形、浮点型和decimal型变量
- a+1与&a+1
- copy
- 洛谷2023维护序列(线段树区间乘+区间加)
- 一道Erlang测试题的多种解法
- 手势操作