NSCopy-NSMutablecopy
- 浅拷贝:不产生新的对象,直接指向原有对象 浅拷贝就是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间。
- 深拷贝:产生新的对象(新地址),其内容是原有对象的内容
NSCopy
拷贝出的结果是不可变对象,跟其接受类型没有关系,跟其传入类型也没有关系,
NSMutablecopy
拷贝的结果是可变对象,跟其传入的类型没有关系,但是会受其接收类型的影响,
当使用
NSCopy
复制一个不可变对象时,其行
为是浅复制,其余情况都是深拷贝
当使用
NSMutablecopy时,是深拷贝
如下:
拷贝行为属于 | 拷贝出的结果 | ||
NSCopy | 复制一个不可变对象 | 浅复制 | 不可变对象 |
复制一个可变对象 | 深拷贝 | ||
NSMutablecopy | 深拷贝 | 受接收类型影响 |
通过一个示例程序来补充下细节
main.m
#import <Foundation/Foundation.h>#import "Person.h"
int main( int argc, const char * argv[]) {
@autoreleasepool {
Person *p = [[ Person alloc ] init ];NSMutableString *s = [ NSMutableString stringWithFormat : @" 汉三 " ]; // 对可变字符串进行操作,地址不会变化,改变的是内容。对不可变字符串的重新赋值,地址内容都会改变。p. name = s; //NSLog ( @"%p,%p" ,p. name ,s); // 打印: 0x100114990,0x100114a80Person *p1 = [p mutableCopy ]; //p 属于 Person 类对象,[]内调用方法必须在该类中存在该方法的协议和实现 // 此处使用: Person *p1 = [p mutableCopy]; 示例NSLog ( @"%@,%@" ,p1,p);
[s setString : @" 王五 " ];
p1. name = s;
NSLog ( @"%@,%@,%p,%p" ,p,p1,p1. name ,s); // 如果不用 copy ,对象属性的值会一直跟着变// 打印 : 0x100300160,0x100114a80}return 0 ;}
Person.h
// 如果自定义类想要实现拷贝操作,首先需要遵循 NSCopying 和 NSMutableCopying 协议,#import <Foundation/Foundation.h>@interface Person : NSObject < NSCopying , NSMutableCopying > // 协议不能少@property ( nonatomic , copy ) NSString *name; //NSCopy 拷贝出的结果是不可变对象@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;
}
}
@end