系统提供的不可变和可变对象
copy/mutableCopy是由NSCopying/NSMutableCopying protocol实现的具体实现如下:
以继承NSArray为例表示(只是模拟):
@interface CopyArray : NSArray
@end
@implementation CopyArray
-(id)copyWithZone:(NSZone *)zone{
return self;
}
-(id)mutableCopyWithZone:(NSZone *)zone{
return [NSMutableArray arrayWithArray:self];
}
@end
对NSArray进行 copy返回self, MutableCopy返回的是一个新创建可变的数组;
以继承NSMutableArray为例表示(只是模拟):
@interface mutableCopyArray : NSMutableArray
@end
@implementation mutableCopyArray
-(id)copyWithZone:(NSZone *)zone{
return [NSArray arrayWithArray:self];
}
-(id)mutableCopyWithZone:(NSZone *)zone{
return [NSMutableArray arrayWithArray:self];
}
@end
对NSMutableArray 进行copy 返回是一个新建的不可变数组, 进行mutableCopy是一个新建的可变数组。
对自定义的类实现NSCopying协议
copy | mutableCopy | |
NSString, NSArray, NSSet, NSDictionary | 返回自身对象 | 返回新建的可变对象 |
NSMutableString, NSMutableArray, NMutableSSet, NSMutableDictionary | 返回新建的不可变对象 | 返回新建的可变对象 |
自定义的类进行NSCopying协议
浅copy
#import "CopyPerson.h"
@interface CopyPerson ()<NSCopying>
@property (nonatomic, copy) NSString *name;
@end
@implementation CopyPerson
-(id)copyWithZone:(NSZone *)zone{
return self;
}
@end
@implementation CopyPerson
-(id)copyWithZone:(NSZone *)zone{
return self;
}
@end
浅copy 返回自身 ,自身的引用计数器+1
深copy
@interface CopyPerson : NSObject <NSCopying>
@property (nonatomic, copy) NSString *name;
@end
@implementation CopyPerson
-(id)copyWithZone:(NSZone *)zone{
CopyPerson *person = [[CopyPerson alloc] init];
person.name = self.name;
return person;
}
@end
深copy 对对象的内容复制到新建的对象上 反对象的引用计数器不变
修饰属性的关键字copy
开发中我们对NSMutableString, NSMutableArray, NSMutableDictionary使用strong修饰 对NSString, NSArray, NSDictionary 使用copy修饰。
NSArray修饰
#import "CopyViewController.h"
@interface CopyViewController ()
@property (nonatomic, strong) NSArray *array1;
@property (nonatomic, copy) NSArray *array2;
@end
@implementation CopyViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *array3 = [NSMutableArray array];
self.array1 = array3;
self.array2 = array3;
}
array1, array2声明的类型是NSArray
经过上面赋值操作, self.array1的实际类型是NSMutableArray, self.array2的类型是NSArray;
strong修饰的array1 是array1指向array3;如果array3 进行修改了array1 也会进行改变
copy修饰的array2 通过copy array3后不可变对象(可变对象经过copy后变成不可变对象,请看上文)
对NSMutableArray修饰
@interface CopyViewController ()
@property (nonatomic, strong) NSMutableArray *mutableArray1;
@property (nonatomic, copy) NSMutableArray *mutableArray2;
@end
@implementation CopyViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *array3 = [NSMutableArray array];
self.mutableArray1 = array3;
self.mutableArray2 = array3;
}
mutableArray1, mutableArray2声明类型NSMutableArray
经过操作后 mutableArray1的类型是NSMutableArray; mutableArray2的类型是NSArray
strong修饰的mutableArray1 指向array3;如果array3 进行修改了array1 也会进行改变且类型和声明一样
copy修饰的mutableArray2 通过copy array3后不可变对象(可变对象经过copy后变成不可变对象,请看上文), 如果对mutableArray2进行可变数组的操作会导致crash。