标签:
1 #import <Foundation/Foundation.h> 2 int main(int argc, const char * argv[]) { 3 @autoreleasepool { 4 NSString * testStr = @"connor"; 5 NSLog(@"testStr‘s Address = %p",testStr); 6 7 NSString * testStrCopy = [testStr copy]; 8 NSLog(@"testStrCopy Address = %p",testStrCopy); 9 10 NSArray * array = @[@1,@2,@3]; 11 NSLog(@"array Address = %p",array); 12 13 NSArray * copyArray = [array copy]; 14 NSLog(@"copyArray Address = %p",copyArray); 15 } 16 return 0; 17 }
输出结果如下:
DataStruct[11210:2189074] testStr‘s Address = 0x100004280
DataStruct[11210:2189074] testStrCopy Address = 0x100004280
DataStruct[11210:2189074] array Address = 0x100300650
DataStruct[11210:2189074] copyArray Address = 0x100300650
1 #import <Foundation/Foundation.h> 2 #import "Father.h" 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 NSString * test = @"a"; 6 NSLog(@"%p",test); 7 8 NSString * testCopy = [test mutableCopy]; 9 NSLog(@"%p",testCopy); 10 } 11 return 0; 12 }
输出结果如下:
DataStruct[11355:2249168] 0x100004280
DataStruct[11355:2249168] 0x100203cf0
1 /** .h */ 2 #import <Foundation/Foundation.h> 3 @interface Father : NSObject<NSCopying> 4 @property(nonatomic,copy)NSString * name; 5 @end 6 7 /** .m */ 8 #import "Father.h" 9 10 @implementation Father 11 -(id)copyWithZone:(NSZone *)zone{ 12 Father * copyFather = [[self class]allocWithZone:zone]; 13 return copyFather; 14 } 15 @end
写好了Father类我们在外界就可以利用copy的方法去copy出一个Father对象
1 #import <Foundation/Foundation.h> 2 #import "Father.h" 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 Father * fatherA = [[Father alloc]init]; 6 fatherA.name = @"connor"; 7 NSLog(@"%p",fatherA); 8 9 Father * fatherB = [fatherA copy]; 10 NSLog(@"%@",fatherB.name); 11 NSLog(@"%p",fatherB); 12 } 13 return 0; 14 }
输出结果:
DataStruct[11383:2256524] 0x100206c80
DataStruct[11383:2256524] (null)
DataStruct[11383:2256524] 0x100300600
从输出结果来看,两个Father实例的内存地址是不一样的我们实现了深拷贝。但是为什么第二个Father没有名字?在拷贝过程过虽然我是从你FatherA拷贝过来的,但是你并没有指定FatherA中的属性到底是什么方式拷贝过来。所以这里面如果想要实现名字也拷贝过来,需要我们自己去定义到底是深拷贝过来还是浅拷贝过来。这也符合苹果做事的风格嘛。
1 #import "Father.h" 2 //添加name的浅拷贝 3 @implementation Father 4 -(id)copyWithZone:(NSZone *)zone{ 5 Father * copyFather = [[self class]allocWithZone:zone]; 6 copyFather.name = [self.name copy]; //如果想要深拷贝过来直接mutableCopy即可 7 return copyFather; 8 } 9 @end
结果输出两个name的内存地址:
DataStruct[11409:2261412] 0x100004290
DataStruct[11409:2261412] 0x100004290
1 /** .h */ 2 #import <Foundation/Foundation.h> 3 4 @interface Car : NSObject<NSCopying> 5 @property(nonatomic,copy)NSString * brand; 6 @end 7 8 /** .m */ 9 @implementation Car 10 -(id)copyWithZone:(NSZone *)zone{ 11 Car * copyCar = [[self class]allocWithZone:zone]; 12 copyCar.brand = [self.brand mutableCopy]; 13 return copyCar; 14 } 15 @end
/** .h */ #import <Foundation/Foundation.h> #import "Car.h" @interface Father : NSObject<NSCopying> @property(nonatomic,copy)NSString * name; @property(nonatomic,strong)Car * car; @end /** .m */ #import "Father.h" @implementation Father -(id)copyWithZone:(NSZone *)zone{ Father * copyFather = [[self class]allocWithZone:zone]; copyFather.name = [self.name copy]; copyFather.car = [self.car copy]; return copyFather; } @end
#import <Foundation/Foundation.h> #import "Father.h" #import "Car.h" int main(int argc, const char * argv[]) { @autoreleasepool { Father * fatherA = [[Father alloc]init]; fatherA.car = [[Car alloc]init]; NSLog(@"%p",fatherA.car); Father * fatherB = [fatherA copy]; NSLog(@"%p",fatherB.car); } return 0; }
输出结果:
DataStruct[11441:2268004] 0x100111f60
DataStruct[11441:2268004] 0x1001154a0
1 /** .h */ 2 #import "Father.h" 3 @interface Son : Father 4 @property(nonatomic,copy)NSString * toy; 5 @end 6 7 /** .m */ 8 #import "Son.h" 9 @implementation Son 10 @end
1 #import <Foundation/Foundation.h> 2 #import "Son.h" 3 int main(int argc, const char * argv[]) { 4 @autoreleasepool { 5 Son * sonA = [[Son alloc]init]; 6 sonA.name = @"connor"; 7 sonA.toy = @"iPhone"; 8 9 Son * sonB = [sonA copy]; 10 11 NSLog(@"sonA‘s Address = %p",sonA); 12 NSLog(@"sonB‘s Address = %p",sonB); 13 14 NSLog(@"sonA‘s name Address = %p",sonA.name); 15 NSLog(@"sonB‘s name Address = %p",sonB.name); 16 17 NSLog(@"sonA‘s toy Address = %p",sonA.toy); 18 NSLog(@"sonB‘s toy Address = %p",sonB.toy); 19 } 20 return 0; 21 }
输出结果:
DataStruct[11563:2279201] sonA‘s Address = 0x100114bc0
DataStruct[11563:2279201] sonB‘s Address = 0x100111f70
DataStruct[11563:2279201] sonA‘s name Address = 0x100004260
DataStruct[11563:2279201] sonB‘s name Address = 0x726f6e6e6f6365
DataStruct[11563:2279201] sonA‘s toy Address = 0x100004280
DataStruct[11563:2279201] sonB‘s toy Address = 0x0 这个结果也在我们意料之内的嘛,Son是继承与Father类的,Father实现了Copy协议,所以这个copy协议实现会继承到子类。我的理解其实:当Son调用Copy方法的时候就将消息转发给Son抽象类,发现Son中没有实现Copt则向Father发送消息SuperSendMsg就相当于事件响应链传递一样。一直向上传递直到能被处理。**这里需要注意一点Father中 Father * copyFather = [[self class]allocWithZone:zone];这里用的是self而不是Father因为Son会走到这里来,我们不能限制死到底是谁来调用***。接下来我们继续看为什么toy是个空置,这个原因和上面说的嵌套copy有点类似。因为Father不清楚你Son的属性到底是怎么copy过来的。那么怎么修改呢?我们只要在toy中稍作修改即可
1 @implementation Son 2 -(id)copyWithZone:(NSZone *)zone{ 3 //这句话保证父类的copy也被call到 4 Son * son = [super copyWithZone:zone]; 5 son.toy = [self.toy mutableCopy]; 6 return son; 7 } 8 @end
输出结果:toy成功被深拷贝
DataStruct[11606:2301994] sonA‘s toy Address = 0x100004288
DataStruct[11606:2301994] sonB‘s toy Address = 0x656e6f68506965
1 #import "Son.h" 2 @implementation Son 3 -(id)copyWithZone:(NSZone *)zone{ 4 // Son * son = [super copyWithZone:zone]; 5 Son * son = [[self class] allocWithZone:zone]; 6 son.name = [self.name mutableCopy]; 7 son.toy = [self.toy mutableCopy]; 8 return son; 9 } 10 @end
输出结果:
DataStruct[11660:2317623] sonA‘s Address = 0x100206e00
DataStruct[11660:2317623] sonB‘s Address = 0x1002040e0
DataStruct[11660:2317623] sonA‘s name Address = 0x100004260
DataStruct[11660:2317623] sonB‘s name Address = 0x726f6e6e6f6365
DataStruct[11660:2317623] sonA‘s toy Address = 0x100004280
DataStruct[11660:2317623] sonB‘s toy Address = 0x656e6f68506965
iOS开发那些事儿(五)Objective-C浅拷贝与深拷贝
标签:
原文地址:http://www.cnblogs.com/conorBlogs/p/5535256.html