OC内部:可变对象和不可变对象的深(复制)拷贝问题思考:
1:对于不可变对象,copy都是浅复制,即指针复制。mutableCopy 都是Alloc一个新对象返回。
2:对于可变对象,copy和mutableCopy都是Alloc新对象返回。
3:不论是可变还是不可变对象,copy返回的对象都是不可变的,mutableCopy返回的对象都是可变的。
4:容器类对象,不论是可变的还是不可变的,copy,mutableCopy返回的对象里所包含的对象的地址和之前都是一样 的,即容器内对象都是浅拷贝。
一、不可变对象的深复制
// Person.h
// 测试
//
// Created by ma c on 15/8/15.
// Copyright (c) 2015年. All rights reserved.
// #import <Foundation/Foundation.h> @interface Person : NSObject<NSCopying>
@property(nonatomic,copy)NSString *name;
-(id)initWithName:(NSString *)name;
-(void)print;
@end
// Person.m
// 测试
//
// Created by ma c on 15/8/15.
// Copyright (c) 2015年. All rights reserved.
// #import "Person.h" @implementation Person
-(id)initWithName:(NSString *)name
{
self = [super init];
if(self)
{
_name = [name mutableCopy]; //不可变深复制mutableCopy
//_name = [name copy];//不可变深复制copy
}
return self;
} -(id)copyWithZone:(NSZone *)zone
{
return [[Person alloc]initWithName:_name];
}
@end
主函数测试
- // main.m
- // 测试
- //
- // Created by ma c on 15/8/15.
- // Copyright (c) 2015年. All rights reserved.
- //
- #import <Foundation/Foundation.h>
- #import "Person.h"
- int main(int argc, const char * argv[])
- {
- @autoreleasepool
- {
- NSMutableString *name = [NSMutableString stringWithString:@"Jobs"];
- Person *p1 = [[Person alloc]initWithName:name];
- NSLog(@"%@----%p",name,p1.name);
- Person *p2 = [p1 copy];
- NSLog(@"%@----%p",name,p2.name);
- [name appendString:@"Tom"];
- Person *p3 = [[Person alloc]initWithName:name];
- NSLog(@"%@----%p",name,p3.name);
- Person *p4 = [p3 copy];
- NSLog(@"%@----%p",name,p4.name);
- }
- return 0;
- }
测试结果如下:
2015-08-15 22:14:33.544 测试[2042:151149] Jobs----0x100206d10
2015-08-15 22:14:33.545 测试[2042:151149] Jobs----0x100300360
2015-08-15 22:14:33.545 测试[2042:151149] JobsTom----0x100300410
2015-08-15 22:14:33.545 测试[2042:151149] JobsTom----0x100400010
Program ended with exit code: 0
以上结果为mutableCopy深复制的结果:复制后一样的内容,可是各自所在的地址值是不同的,说明了系统为新创建的对象开辟了内存,这就是真正意义的深复制。
2015-08-15 22:15:08.773 测试[2050:151390] Jobs----0x100206d10
2015-08-15 22:15:08.774 测试[2050:151390] Jobs----0x100206d10
2015-08-15 22:15:08.775 测试[2050:151390] JobsTom----0x100207810
2015-08-15 22:15:08.775 测试[2050:151390] JobsTom----0x100207810
Program ended with exit code: 0
以上结果为copy深复制结果,可以看出复制后一样的内容,可是它们的地址值是一样,说明了这并不是真正意义的深复制,而是假深复制,即最终结果是只是复制了指针。
二、可变对象的深复制
// Person.h
// 测试
//
// Created by ma c on 15/8/15.
// Copyright (c) 2015年. All rights reserved.
// #import <Foundation/Foundation.h> @interface Person : NSObject<NSCopying>
@property(nonatomic,copy)NSMutableString *name;
-(id)initWithName:(NSMutableString *)name;
-(void)print;
@end
// Person.m
// 测试
//
// Created by ma c on 15/8/15.
// Copyright (c) 2015年. All rights reserved.
// #import "Person.h" @implementation Person
-(id)initWithName:(NSMutableString *)name
{
self = [super init];
if(self)
{
//_name = [name copy];//可变深复制copy
_name = [name mutableCopy];//可变深复制mutableCopy
}
return self;
}
-(id)copyWithZone:(NSZone *)zone
{
return [[Person alloc]initWithName:_name];
}
@end
主函数测试
// main.m
// 测试
//
// Created by ma c on 15/8/15.
// Copyright (c) 2015年. All rights reserved.
// #import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[])
{
@autoreleasepool
{
NSMutableString *name = [NSMutableString stringWithString:@"Jobs"]; Person *p1 = [[Person alloc]initWithName:name];
NSLog(@"%@----%p",name,name);
NSLog(@"%@----%p",p1.name,p1.name); }
return ;
}
测试结果如下:
-- ::12.110 测试[:] Jobs----0x1001002d0
-- ::12.111 测试[:] Jobs----0x100106c90
Program ended with exit code: 以上结果为可变对象的复制,采用copy复制时,复制出的内容是一样的,但是它们的地址值是不相同的,所以这是真正意义的深复制。
-- ::05.744 测试[:] Jobs----0x1001147a0
-- ::05.745 测试[:] Jobs----0x100114a40
Program ended with exit code: 以上结果为可变对象的复制,采用mutableCopy复制时,复制出的内容也是一样的,但是它们的地址值也是不同的,这也是真正意义的深复制。