OC学习 第十二章 深拷贝 浅拷贝 NSCopy NSMutablecopy
一、基本概念
拷贝分为深拷贝和浅拷贝
浅拷贝:不产生新的对象,直接指向原有对象。
深拷贝:产生新的对象,其内容是原有对象的内容。
二、OC数据类型拷贝
NSCopy拷贝出的结果是不可变对象
,跟其接受类型没有关系,跟其传入类型也没有关系,NSMutablecopy拷贝的结 果 是 可 变 对 象,跟 其 传 入 的 类 型 没 有 关 系,但是会受其接收类型的影响。
当使用NSCopy复制一个不可变对象时,其行为是浅拷贝,其余情况都是深拷贝。
如: 1、不可变对象 NSString *str = @"123";
NSString *str1 = [str copy];
NSLog(@"%p %p",str,str1);输出str地址跟str1地址相同,说明浅拷贝。
2、 可变对象 NSMutableString *str = [NSMutableString stringWithString:@"123"];
NSMutableString *str1 = [str copy];
NSLog(@"str=%p str1= %p",str,str1);输出结果(地址)不同,说明深拷贝。
str=0x100206b40 str1= 0x100202f30
当使用NSMutablecopy时,是深拷贝
例:
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
/* NSCopying
NSString *str = [NSString stringWithFormat:@"123"];
NSString *str1 = [str copy];
NSMutableString *str2 = [str copy];
NSMutableString *str3 = [NSMutableString stringWithFormat:@"222"];
NSString *str4 = [str3 copy];
NSLog(@"%p,%p",str1,str);
NSMutableCopy
NSString *str = [NSString stringWithFormat:@"123"];
NSMutableString *s = [str mutableCopy];
[s setString:@"23"];
NSLog(@"%p,%p",s,str);
}
return 0;
}
三、自定义对象拷贝
当需要拷贝的是自定义类的对象时,必须要遵守NSCopy和NSMutableCopy协议,且实现其方法。
例:有一个Person类
Person.h文件:
#import
<Foundation/Foundation.h>
@interface Person : NSObject < NSCopying , NSMutableCopying >(必须遵守协议)
@property ( nonatomic , copy ) NSString *name;
@interface Person : NSObject < NSCopying , NSMutableCopying >(必须遵守协议)
@property ( nonatomic , copy ) NSString *name;
@end
Person.m文件:
#import
"Person.h"
@implementation Person
-( NSString *)description{
return _name ;
}
// 如果直接 return self ,则是浅拷贝,如果使用 alloc ,则是深拷贝
-( id )copyWithZone:( NSZone *)zone{
Person *p = [ Person allocWithZone :zone];
// p.name = [self.name copy];
return p;
}
// 如果直接 return self ,则是浅拷贝,如果使用 alloc ,则是深拷贝
-( id )mutableCopyWithZone:( NSZone *)zone{
Person *p = [ Person allocWithZone :zone];
// p.name = [self.name copy];
return p;
}
@implementation Person
-( NSString *)description{
return _name ;
}
// 如果直接 return self ,则是浅拷贝,如果使用 alloc ,则是深拷贝
-( id )copyWithZone:( NSZone *)zone{
Person *p = [ Person allocWithZone :zone];
// p.name = [self.name copy];
return p;
}
// 如果直接 return self ,则是浅拷贝,如果使用 alloc ,则是深拷贝
-( id )mutableCopyWithZone:( NSZone *)zone{
Person *p = [ Person allocWithZone :zone];
// p.name = [self.name copy];
return p;
}
@end
main.m文件:
Person
*p = [[
Person
alloc
]
init
];
NSMutableString *s = [NSMutableString stringWithFormat:@"汉三"];
p.name = s;
Person
*p1 = [p
mutableCopy
];
[s setString : @" 王五 " ];
p1. name = s;
[s setString : @" 王五 " ];
p1. name = s;
NSLog(@"%@,%@",p,p1);
注意:如果不用copy, Person *p = [[Person alloc] init];
NSMutableString *s = [NSMutableString stringWithFormat:@"汉三"];
p.name = s;
[s setString:@"王五"];
NSLog(@"%@",p);
这段代码中,对象属性的值会一直跟着变,也就是说如果是可变的对象,值改变后地址不改变,如果是不可变的对象,值改变后地址也跟着改变;