深拷贝:对象和内存地址均发生改变
浅拷贝:只是单纯地拷贝指针。其地址快并没有发生任何改变
NSString
copy:拷贝指针 不发生地址改变
mutableCopy:对象、地址都发生改变
NSMutableString
copy: 对象、地址都发生改变
mutableCopy:对象、地址都发生改变
NSDictionary
copy:拷贝指针 不发生地址改变
mutableCopy:对象、地址都发生改变
NSMutableDictionary
copy: 对象、地址都发生改变
mutableCopy:对象、地址都发生改变
NSArray
copy:拷贝指针 不发生地址改变
mutableCopy:对象、地址都发生改变
NSMutableArray
copy: 对象、地址都发生改变
mutableCopy:对象、地址都发生改变
自定义对象
copy: 对象、地址都发生改变
mutableCopy:对象、地址都发生改变
例子:
@interface ClassA
@peroroty(copy,nonamatic)NSString* name;
@end
ClassA * a1 = [Class alloc] init];
ClassA* a2 = [a1 copy];
ClassA* a3 = [a1 mutableCopy];
这里会报错 注意
因为我们并没有执行自定义类的“copyWithZone”方法
所以在ClassA中声明协议
@interface ClassA : NSObject<NSCopying, NSMutableCopying>
在在.m中写
- (instancetype) copyWithZone:(NSZone*)zone {
ClassA *a = [[ClassA allocWithZone:zone] init];
a.name =self.name;//这里要进行属性变量赋值 不然copy是不会进行拷贝的
NSLog(@"没有copyWithZone自定义对象就不能copy");
return a;
}
- (instancetype) mutableCopyWithZone:(NSZone*)zone {
ClassA *a = [[ClassA allocWithZone:zone] init];
a.name =self.name;//这里要进行属性变量赋值 不然mutableCopy是不会进行拷贝的
NSLog(@"没有mutableCopyWithZone自定义对象就不能copy");
return a;
}
进阶:copy和strong的用法和区别
例子:
#import"ViewController.h"
@interfaceViewController()
@property(nonatomic,copy)NSString*str;
@end
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
NSMutableString*strM = [[NSMutableStringalloc] initWithString:@"bestDay"];
self.str = strM;
[strM appendString:@"OfThisYear"];
NSLog(@"str----%@---%p",self.str,self.str);
NSLog(@"strM----%@---%p",strM,strM);
}
@end
输出:
2018-04-1408:53:01.874strong修饰不同[789:18128]str----bestDay---0xa796144747365627
2018-04-1408:53:01.875strong修饰不同[789:18128]strM----bestDayOfThisYear---0x600000071280
可以看到copy修饰的str,在赋值以后,可变字符串strM发生了变化并不会影响str的值。从打印结果来看是因为二者不是一个地址,所以不会相互影响。为什么?是因为copy修饰的属性setter方法,走的是先release旧值,copy新值再赋值给成员变量,不可变copy是深拷贝,就是内容拷贝,地址变化了。
如果换成strong的话
strong修饰以后只是强指针引用,并未改变地址,所以str的值会随着strM进行变化,二者的地址也是相同的。
总结:
1.原对象和拷贝对象都是不可变对象时,为浅拷贝。
2.其他情况均为深拷贝。