以前在oc中,如果一个属性比如NSArray,如果使用copy来修饰,则是不可变的.
@property (nonatomic, copy) NSMutableArray *nmArray;
当给nmArray赋值一个可变的数组对象时,用copy修饰则代表它会进行一次copy操作,则变为不可变对象.
NSMutableArray *arr = [NSMutableArray arrayWithArray:@[@"1", @"2"]];
_nmArray = arr;
[_nmArray removeLastObject];
NSLog(@"nmArray = %@", _nmArray);
这段代码在以前的oc中是会造成crash的,因为不可变的数组是不能操作的.
但是现在试了一下,并不会造成crash._nmArray还是可以进行增删的操作.
查看_nmArray的内存地址,发现copy和strong一样,都是只拷贝了指针的浅拷贝.
// 声明
@property (nonatomic, copy) NSMutableArray *nmCopyArray;
@property (nonatomic, strong) NSMutableArray *nmStrongArray;
// 赋值
NSMutableArray *arr = [NSMutableArray arrayWithArray:@[@"1", @"2"]];
_nmCopyArray = arr;
_nmStrongArray = arr;
[arr removeLastObject];
NSLog(@"arr = 指针 %p 内存 %p", &arr, arr);
NSLog(@"nmArray = 指针 %p 内存 %p", &_nmCopyArray, _nmCopyArray);
NSLog(@"nmStrongArray = 指针 %p 内存 %p", &_nmStrongArray, _nmStrongArray);
// 打印
arr = 指针 0x7ffee5db6020 内存 0x6000015430c0
nmArray = 指针 0x7fac07f08940 内存 0x6000015430c0
nmStrongArray = 指针 0x7fac07f08948 内存 0x6000015430c0
有可能是OC的实现发生了改变;
数组的copy和mutableCopy
针对可变数组和不可变数组测试copy和mutableCopy:
不可变数组的copy是浅拷贝, mutableCopy是深拷贝
可变数组的copy和mutableCopy都是深拷贝,这和以前是一样的.
NSString的copy和mutableCopy
使用copy修饰的NSString属性,当赋值了一个NSMutableString时,也是进行了浅拷贝,这使得copy和strong基本没有区别的.
// 声明
@property (nonatomic, copy) NSString *copyname;
@property (nonatomic, strong) NSString *strongName;
// 赋值
NSMutableString *nmStr = [[NSMutableString alloc]initWithString:@"zhang"];
_copyname = nmStr;
_strongName = nmStr;
NSLog(@"nmStr - %@ - 指针 %p - 地址 %p", nmStr, &nmStr, nmStr);
NSLog(@"copyname - %@ - 指针 %p - 地址 %p", _copyname, &_copyname, _copyname);
NSLog(@"strongname - %@ - 指针 %p - 地址 %p", _strongName, &_strongName, _strongName);
[nmStr appendString:@"san"];
NSLog(@"nmStr - %@ - 指针 %p - 地址 %p", nmStr, &nmStr, nmStr);
NSLog(@"copyname - %@ - 指针 %p - 地址 %p", _copyname, &_copyname, _copyname);
NSLog(@"strongname - %@ - 指针 %p - 地址 %p", _strongName, &_strongName, _strongName);
// 打印
nmStr - zhang - 指针 0x7ffeeedf0010 - 地址 0x600000936ee0
copyname - zhang - 指针 0x7fdbca107780 - 地址 0x600000936ee0
strongname - zhang - 指针 0x7fdbca107788 - 地址 0x600000936ee0
nmStr - zhangsan - 指针 0x7ffeeedf0010 - 地址 0x600000936ee0
copyname - zhangsan - 指针 0x7fdbca107780 - 地址 0x600000936ee0
strongname - zhangsan - 指针 0x7fdbca107788 - 地址 0x600000936ee0
以前认为copy属性是进行了一次 [str copy] 的深拷贝操作,str的引用计数不增加.
现在应该是只发生了浅拷贝,查看下引用计数:
NSLog(@"nmStr retaincount copy前 - %ld", CFGetRetainCount((__bridge CFTypeRef)(nmStr)));
NSString *string11 = [nmStr copy];
NSLog(@"string11 - %@ - 指针 %p - 地址 %p", string11, &string11, string11);
NSLog(@"nmStr retaincount copy后 - %ld", CFGetRetainCount((__bridge CFTypeRef)(nmStr)));
// 打印
nmStr retaincount copy前 - 3
string11 - zhangsan - 指针 0x7ffeeddd5018 - 地址 0xcb73896b9d84e74e
nmStr retaincount copy后 - 3
在对nmStr进行copy操作后,nmStr的引用计数没有增加,说明copy是深拷贝,后面的string11的地址也说明了这点.所以属性用copy修饰并不是深拷贝了.