简介
Objective-C
对象是通过指向该对象内存地址的指针,以 间接
方式访问的。
指针赋值
概念
对于实现了NSCopying与NSMutableCopying协议的对象来说,指针赋值并非简单的赋值,还有额外的操作:
- 浅拷贝
类似于ARC下的指针赋值,将一个新指针指向该内存地址;
- 深拷贝
将一个新指针指向新的内存对象,该内存的数据与被复制的数据相同!如果改变原内存数据,新对象不会随着改变!
非容器类:字符串
注:__NSCFConstantString
代表不可变,__NSCFString
代表可变
- 不可变字符串NSString
1 2 3 4 5 6 7 8 9 10 11 12
| // 不可变的字符串 NSString *string = @"string"; NSString *string_1 = [string copy]; NSMutableString *string_2 = [string mutableCopy]; NSLog(@"string : %@ %p",[string class],string); NSLog(@"string_1 : %@ %p",[string_1 class],string_1); NSLog(@"string_2 : %@ %p",[string_2 class],string_2); ******打印结果****** 2020-08-12 20:10:15.022910+0800 OC-copy和mutableCopy[39668:2403350] string : __NSCFConstantString 0x10a9bd028 2020-08-12 20:10:15.023183+0800 OC-copy和mutableCopy[39668:2403350] string_1 : __NSCFConstantString 0x10a9bd028 2020-08-12 20:10:15.023983+0800 OC-copy和mutableCopy[39668:2403350] string_2 : __NSCFString 0x600000e395c0
|
由结果可知:
copy指向同一个内存地址,指针拷贝,即浅拷贝,返回不可变类型
mutable指向不同的内存地址,深拷贝,返回可变类型
- 可变字符串NSMutableString
1 2 3 4 5 6 7 8 9 10 11 12
| //可变的字符串 NSMutableString * mutableStr = [NSMutableString stringWithString:@"mutableStr"]; NSMutableString *mutableString_1 = [mutableStr copy]; NSMutableString *mutableString_2 = [mutableStr mutableCopy]; NSLog(@"mutableStr : %@ %p",[mutableStr class],mutableStr); NSLog(@"mutableString_1 : %@ %p",[mutableString_1 class],mutableString_1); NSLog(@"mutableString_2 : %@ %p",[mutableString_2 class],mutableString_2);
******打印结果****** 2020-08-12 20:11:36.024015+0800 OC-copy和mutableCopy[39698:2404773] mutableStr : __NSCFString 0x600003bf9d10 2020-08-12 20:11:36.024163+0800 OC-copy和mutableCopy[39698:2404773] mutableString_1 : __NSCFString 0x6000035f5400 2020-08-12 20:11:36.024275+0800 OC-copy和mutableCopy[39698:2404773] mutableString_2 : __NSCFString 0x600003bf9e60
|
由结果可知:
copy指向不同的内存地址,深拷贝,返回可变类型
mutable指向不同的内存地址,深拷贝,返回可变类型
容器类:
数组
- 不可变数组
注: __NSArrayI
代表不可变,__NSArrayM
代表可变
1 2 3 4 5 6 7 8 9 10 11 12
| //不可变数组 NSArray *arr = @[@"1",@"2"]; NSArray *arr_1 = arr.copy; NSMutableArray *arr_2 = arr.mutableCopy; NSLog(@"arr : %@ %p",[arr class],arr); NSLog(@"arr_1 : %@ %p %p",[arr_1 class],arr_1,arr_1[0]); NSLog(@"arr_2 : %@ %p %p",[arr_2 class],arr_2,arr_2[0]);
******打印结果****** 2020-08-25 17:52:40.585722+0800 OC-copy和mutableCopy[43144:2152457] arr : __NSArrayI 0x600000a6b8e0 2020-08-25 17:52:40.585927+0800 OC-copy和mutableCopy[43144:2152457] arr_1 : __NSArrayI 0x600000a6b8e0 0x101024128 2020-08-25 17:52:40.586054+0800 OC-copy和mutableCopy[43144:2152457] arr_2 : __NSArrayM 0x600000471980
|
由上面的结果可知:
copy指向同一个内存地址,浅拷贝,返回不可变类型
mutableCopy指向不同的内存地址,深拷贝,返回可变类型
不可变数组中的元素指向同一个内存地址,浅拷贝
- 可变数组
1 2 3 4 5 6 7 8 9 10 11 12
| //可变数组 NSMutableArray * mutableArr = [NSMutableArray arrayWithObjects:@"1",@"2", nil]; NSArray *mutableArr_1 = mutableArr.copy; NSMutableArray *mutableArr_2 = mutableArr.mutableCopy; NSLog(@"mutableArr : %@ %p",[mutableArr class],mutableArr); NSLog(@"copyArr_1 : %@ %p %p",[mutableArr_1 class],mutableArr_1,mutableArr_1[0]); NSLog(@"mutableCopyArr_2 : %@ %p %p",[mutableArr_2 class],mutableArr_2,mutableArr_2[0]); ******打印结果****** 2020-08-25 17:52:40.586501+0800 OC-copy和mutableCopy[43144:2152457] mutableArr : __NSArrayM 0x600000479230 2020-08-25 17:52:40.587261+0800 OC-copy和mutableCopy[43144:2152457] copyArr_1 : __NSArrayI 0x600000a05ec0 0x101024128 2020-08-25 17:52:40.587486+0800 OC-copy和mutableCopy[43144:2152457] mutableCopyArr_2 : __NSArrayM 0x6000004790b0 0x101024128
|
由上面的结果可知:
copy指向不同的内存地址,深拷贝,返回不可变类型
mutableCopy指向不同的内存地址,深拷贝,返回可变类型
可变数组中的元素指向同一个内存地址,浅拷贝
字典
- 不可变字典
1 2 3 4 5 6 7 8 9 10 11 12
| //不可变字典 NSDictionary *dic = @{@"1":@"z",@"2":@"j"}; NSDictionary *dic_1 = dic.copy; NSMutableDictionary *dic_2 = dic.mutableCopy; NSLog(@"dic : %@ %p",[dic class],dic); NSLog(@"dic_1 : %@ %p %p",[dic_1 class],dic_1,dic_1[@"1"]); NSLog(@"dic_2 : %@ %p %p",[dic_2 class],dic_2,dic_2[@"1"]);
******打印结果****** 2020-08-25 18:02:07.764010+0800 OC-copy和mutableCopy[43252:2160581] dic : __NSDictionaryI 0x600002acbac0 2020-08-25 18:02:07.764194+0800 OC-copy和mutableCopy[43252:2160581] dic_1 : __NSDictionaryI 0x600002acbac0 0x10f0cb228 2020-08-25 18:02:07.764331+0800 OC-copy和mutableCopy[43252:2160581] dic_2 : __NSDictionaryM 0x600003fb1ea0 0x10f0cb228
|
由结果可知:
copy指向同一个内存地址,浅拷贝,返回不可变类型
mutableCopy指向不同的内存地址,深拷贝,返回可变类型
不可变字典中的元素指向同一个内存地址,浅拷贝
- 可变字典
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| //可变字组 NSMutableDictionary * mutableDic = [NSMutableDictionary dictionaryWithDictionary:@{@"1":@"z",@"2":@"z"}]; NSArray *mutableDic_1 = mutableDic.copy; NSMutableArray *mutableDic_2 = mutableDic.mutableCopy; //可变字典 NSMutableDictionary * mutableDic = [NSMutableDictionary dictionaryWithDictionary:@{@"1":@"z",@"2":@"z"}]; NSDictionary *mutableDic_1 = mutableDic.copy; NSMutableDictionary *mutableDic_2 = mutableDic.mutableCopy; NSLog(@"mutableDic : %@ %p",[mutableDic class],mutableDic); NSLog(@"mutableDic_1 : %@ %p %p",[mutableDic_1 class],mutableDic_1,mutableDic_1[@"1"]); NSLog(@"mutableDic_2 : %@ %p %p",[mutableDic_2 class],mutableDic_2,mutableDic_2[@"1"]); ******打印结果****** 2020-08-25 18:03:42.698800+0800 OC-copy和mutableCopy[43295:2162720] mutableDic : __NSDictionaryM 0x6000023efb00 2020-08-25 18:03:42.699266+0800 OC-copy和mutableCopy[43295:2162720] mutableDic_1 : __NSFrozenDictionaryM 0x6000023ef8a0 0x10602a228 2020-08-25 18:03:42.699646+0800 OC-copy和mutableCopy[43295:2162720] mutableDic_2 : __NSDictionaryM 0x6000023ef800 0x10602a228
|
由结果可知:
copy指向不同的内存地址,深拷贝,返回不可变类型
mutableCopy指向不同的内存地址,深拷贝,返回可变类型
可变字典中的元素指向同一个内存地址,浅拷贝
非容器类:自定义对象
要支持copy与mutableCopy,需要实现NSCopying,NSMutableCopying协议。
(Foundation框架对象都实现了该协议,所以可以直接使用copy与mutableCopy,UIKit框架不可以)
用法如下:
自定义person类中实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @interface Person @interface Person : NSObject<NSCopying,NSMutableCopying> @property (nonatomic,copy)NSString * name; @property (nonatomic,assign)int age; @end @implementation Person - (id)copyWithZone:(NSZone *)zone{ Person *person = [Person allocWithZone:zone]; person.name = self.name; person.age = self.age; return person; } - (id)mutableCopyWithZone:(NSZone *)zone{ Person *person = [Person allocWithZone:zone]; person.name = self.name; person.age = self.age; return person; } @end
|
调用:
1 2 3 4 5 6 7 8 9 10 11 12
| // 简单的调用代码 Person *person = [[Person alloc] init]; Person *copyPerson = [person copy]; Person *mutableCopyPerson = [person mutableCopy]; NSLog(@"person : %@ %p",[person class],person); NSLog(@"copyPerson : %@ %p",[copyPerson class],copyPerson); NSLog(@"mutableCopyPerson : %@ %p",[mutableCopyPerson class],mutableCopyPerson); *******打印结果******** 2020-08-12 20:49:20.832411+0800 OC-copy和mutableCopy[40043:2426556] person : Person 0x600000e7f500 2020-08-12 20:49:20.832594+0800 OC-copy和mutableCopy[40043:2426556] copyPerson : Person 0x600000e7f540 2020-08-12 20:49:20.832703+0800 OC-copy和mutableCopy[40043:2426556] mutableCopyPerson : Person 0x600000e7f680
|
由结果可知:
copy指向不同的内存地址,深拷贝,返回本类
mutableCopy指向不同的内存地址,深拷贝,返回本类
总结
注:容器类中的元素都是浅拷贝,因为指向同一个内存地址