OC细节
发布时间:2015-11-09 10:00:45
概述拷贝:复制一个与源对象内容相同的对象实现拷贝,需要遵守以下两个协议NSCopyingNSMutableCopying拷贝返回对象的种类可变,mutableCopy消息返回的对象不可变,copy消息返回的对象拷贝的种类浅拷贝,只是复制了一个指向源对象的指针,未创建对象,未分配内 ...
概述
- 拷贝:复制一个与源对象内容相同的对象
实现拷贝,需要遵守以下两个协议
- NSCopying
- NSMutableCopying
拷贝返回对象的种类
- 可变,mutableCopy消息返回的对象
- 不可变,copy消息返回的对象
拷贝的种类
- 浅拷贝,只是复制了一个指向源对象的指针,未创建对象,未分配内存
- 深拷贝,复制了源对象,创建了新对象,分配了内存
注意
- 系统对容器类的对象与非容器类的对象的内存处理是不同的,即当一个没有被其他对象强引用的对象从容器中移除后,该对象就销毁
Copy与Retain
copy
- 是创建一个新的对象,内容拷贝
- copy表示的是两个对象的内容相同, 新对象的引用计数为1
- 与旧对象的引用计数无关,就对象没有变化
- copy减少了对象对上下文的
retain
- 创建的是一个指针,指针拷贝
- 对象地址相同,内容固然相同
- 对象的引用计数+1
不同对象的拷贝行为
非容器对象(如NSString
))
对于不可变对象
规则
- copy,浅拷贝(指针复制)
- mutableCopy,深拷贝(对象复制),返回对象可变(产生新的 可变对象)
示例
- (void)imutableInstanceCopy{ NSString *string = @"Welcome to Xcode"; //copy,浅拷贝 NSString *stringCopy = [string copy]; //mutableCopy,返回的对象可变 NSMutableString *stringMutableCopy = [string mutableCopy]; [stringMutableCopy appendString:@"!"]; //string与stringCopy的内存地址相同 NSLog(@"string: %p", string); NSLog(@"strongCopy: %p", stringCopy); //string与stringMutableCopy的内存地址不同,分配了新的内存 NSLog(@"stringMCopy:%p", stringMutableCopy);}
对于可变对象
规则
- copy,深拷贝(对象复制),返回对象不可变
- mutableCopy,深拷贝(对象复制)
示例
- (void)mutableInstanceCopy{ NSMutableString *mutableString = [NSMutableString stringWithString: @"Welcome to Xcode"]; //深拷贝,返回对象不可变 NSString *stringCopy = [mutableString copy]; NSMutableString *mutableStringCopy = [mutableString copy]; //运行时,此句会报错,错误信息“Attempt to mutate immutable object with appendString:” [mutableStringCopy appendString:@"~~~"]; //深拷贝,返回对象可变 NSMutableString *stringMutableCopy = [mutableString mutableCopy]; [stringMutableCopy appendString:@"!"]; //三者与mutableString的内存地址都不同 NSLog(@"mutableString: %p", mutableString); NSLog(@"string: %p", stringCopy); NSLog(@"mutableStringCopy: %p", mutableStringCopy); NSLog(@"stringMutbleCopy:%p", stringMutableCopy);}
容器对象(NSArray
)
- 遵循非容器对象的拷贝原则
注意
- 容器内的元素是指针赋值(浅拷贝)
示例
- (void)containerInstanceShallowCopy{ NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil]; //浅拷贝 NSArray *arrayCopy = [array copy]; //深拷贝 NSMutableArray *arrayMutableCopy = [array mutableCopy]; NSLog(@"array: %p", array); NSLog(@"arrayCopy: %p", arrayCopy); NSLog(@"arrayMutableCopy: %p", arrayMutableCopy); //容器内的对象是浅拷贝,即它们在内存中只有一份 NSMutableString *testString = [array objectAtIndex:0]; [testString appendString:@" you"]; //三个数组的内容同时改变 NSLog(@"array[0]: %@", array[0]); NSLog(@"arrayCopy[0]: %@", arrayCopy[0]); NSLog(@"arrayMutableCopy[0]: %@", arrayMutableCopy[0]);}
实现真正意义上的深复制
- (void)containerInstanceDeepCopy{ NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"Welcome"],@"to",@"Xcode",nil]; //数组内对象是指针复制 NSArray *deepCopyArray = [[NSArray alloc] initWithArray:array]; //真正以上的深复制,数组内对象是对象复制 NSArray *trueDeepCopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:[NSKeyedArchiver archivedDataWithRootObject:array]]; NSLog(@"array: %p", array); NSLog(@"deepCopyArray: %p", deepCopyArray); NSLog(@"trueDeepCopyArray: %p", trueDeepCopyArray); //改变array的第一个元素 [[array objectAtIndex:0] appendString:@" you"]; //只影响deepCopyArray数组的第一个元素 NSLog(@"array[0]: %@", array[0]); NSLog(@"arrayCopy[0]: %@", deepCopyArray[0]); //不影响trueDeepCopyArray数组的第一个元素,是真正意义上的深拷贝 NSLog(@"arrayMutableCopy[0]: %@", trueDeepCopyArray[0]);}
自定义对象
---恢复内容结束---
原标题:OC细节
关键词:
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。