简单点来说的话copy就是复制一个不可以变的类型,mutableCopy复制一个可变的对象
举例子
NSString *str = @"fikk";
NSMutableString *str3 = [str copy];
[str3 appendString:@"aa"]; str是个不可变的字符串,但是虽然这里str3是个可变的字符串,但是复制是个不可变的,所以增加程序会报错
NSMutableString *str2 = [str mutableCopy];
[str2 appendString:@".org"];同理这里是个可变的复制,虽然原来的对象是个不可改变的,但是复制之后依然会改变,程序可以正常的输出
但是复制自定义的对象就有点不同了
首先两步走,
第一步实现foundation框架里的NSCoping和NSMutableCoping协议
第二步在自己定义的类实现里实现copyWithZone方法
{
- (id)copyWithZone:(NSZone *)zone
{
FKDog *dog = [[[self class] allocWithZone:zone] init];
dog.name = [self.name mutableCopy];
dog.age = self.age;
return dog;
}
这里使用copy只是浅复制,只是把指针复制过去,但是指向是同一个对象,后面说
现在写一个测试类
FKDog *dog1 = [[FKDog alloc] init];
dog1.name = [NSMutableString stringWithString:@"复制副本"];
FKDog *dog2 = [dog1 copy];
dog2.age = 12;
输出结果
2015-10-09 17:04:26.398 NSCoping协议[1096:73870] 复制副本
2015-10-09 17:04:26.400 NSCoping协议[1096:73870] 0
2015-10-09 17:04:26.400 NSCoping协议[1096:73870] 复制副本
2015-10-09 17:04:26.400 NSCoping协议[1096:73870] 12
很明显,输出结果相同,因为这里只是单纯的把指针复制给新对象,对象的两个name属性保存的是同一个字符串的地址,当然内容相同了这里做一个修改看看
FKDog *dog1 = [[FKDog alloc] init];
dog1.name = [NSMutableString stringWithString:@"复制副本"];
FKDog *dog2 = [dog1 copy];
dog2.name = [NSMutableString stringWithString:@"复制副本1"];
第一个输出“复制副本”第二个输出“复制副本1”
这是为什么呢,因为我们新创建一块字符串地址,name又指向新的字符串,当然内容也变了,我们也可以验证上面所说了再来看看下面的内容
FKDog *dog1 = [[FKDog alloc] init];
dog1.name = [NSMutableString stringWithString:@"复制副本"];
FKDog *dog2 = [dog1 copy];
[dog2.name replaceCharactersInRange:NSMakeRange(0, 2) withString:@"snopy"];
输出内容是
2015-10-09 17:15:57.231 NSCoping协议[1132:81937] snopy副本
2015-10-09 17:15:57.232 NSCoping协议[1132:81937] 0
2015-10-09 17:15:57.232 NSCoping协议[1132:81937] snopy副本
2015-10-09 17:15:57.232 NSCoping协议[1132:81937] 12
看吧,要改都改了
FKDog *dog = [[[self class] allocWithZone:zone] init];
dog.name = [self.name mutableCopy];
dog.age = self.age;
return dog;
2015-10-09 17:23:04.037 NSCoping协议[1198:84752] 复制副本
2015-10-09 17:23:04.038 NSCoping协议[1198:84752] 0
2015-10-09 17:23:04.038 NSCoping协议[1198:84752] snopy副本
2015-10-09 17:23:04.038 NSCoping协议[1198:84752] 12