一.对象的深浅拷贝
对象要实现拷贝就要实现NSCopying或者NSMutableCoping协议,即实现下面两个函数之一
- (id)copyWithZone:(nullable NSZone *)zone
- (id)mutableCopyWithZone:(nullable NSZone *)zone
- (id)copyWithZone:(nullable NSZone *)zone
- (id)mutableCopyWithZone:(nullable NSZone *)zone
完整的深拷贝实例:
Student类
Student.h 文件
Student.h 文件
#import <Foundation/Foundation.h>
#import "Score.h"
@interface Student : NSObject
@property(strong,nonatomic) NSString *mName;
@property(strong,nonatomic) NSString *mAge;
@property(strong,nonatomic) Score *mScore;
-(id)initWithName:(NSString*)name andAge:(NSString*)age andScore:(Score*)score;
@end
#import "Student.h"
@implementation Student
-(id)initWithName:(NSString*)name andAge:(NSString*)age andScore:(Score*)score{
self = [super init];
self.mName = name;
self.mAge = age;
self.mScore = score;
return self;
}
- (id)copyWithZone:(nullable NSZone *)zone
{
Student *copy = [[[self class] allocWithZone:zone] init];
copy.mName = self.mName;
copy.mAge = self.mAge;
copy.mScore = [self.mScore copy];
return copy;
}
@end
Score类
Score.h文件
#import <Foundation/Foundation.h>
@interface Score : NSObject
@property(strong,nonatomic) NSString *mChinese;
@property(strong,nonatomic) NSString *mEnglish;
-(id)initWithChi:(NSString*)chi andEng:(NSString*)eng;
@end
#import "Score.h"
@implementation Score
-(id)initWithChi:(NSString*)chi andEng:(NSString*)eng{
self = [super init];
self.mChinese = chi;
self.mEnglish = eng;
return self;
}
- (id)copyWithZone:(nullable NSZone *)zone{
Score *copy = [[[self class] allocWithZone:zone] init];
copy.mChinese = self.mChinese;
copy.mEnglish = self.mEnglish;
return copy;
}
@end
测试函数
Score *score = [[Score alloc] initWithChi:@"88" andEng:@"66"];
Student *stu = [[Student alloc] initWithName:@"fufu" andAge:@"20" andScore:score];
/*
1.没有实现copyWithZone直接报错
2.如果copyWithZone中的copy.mScore = [self.mScore copy]改成copy.mScore = self.mScore ,属于浅拷贝
3.如果Score中没有实现copyWithZone,则在Student的copyWithZone不能copy.mScore = [self.mScore copy],也属于浅拷贝
4.综上,Score中实现copyWithZone,在Student的copyWithZone中调copy.mScore = [self.mScore copy],才属于深拷贝
*/
Student *stuCopy = [stu copy];
[stu setMName:@"ufuf"];
[stu.mScore setMChinese:@"90"];
二.容器的深浅拷贝(以NSMutableArray为例)
深拷贝
/*
1.用[[NSMutableArray alloc] initWithArray:muArray copyItems:YES];
2.Student对象实现深拷贝
*/
Score *score1 = [[Score alloc] initWithChi:@"11" andEng:@"11"];
Student *stu1 = [[Student alloc] initWithName:@"fufu" andAge:@"10" andScore:score1];
Score *score2 = [[Score alloc] initWithChi:@"22" andEng:@"22"];
Student *stu2 = [[Student alloc] initWithName:@"tutu" andAge:@"20" andScore:score2];
NSMutableArray *muArray = [[NSMutableArray alloc] initWithObjects:stu1,stu2 ,nil];
NSMutableArray *muArrayCopy = [[NSMutableArray alloc] initWithArray:muArray copyItems:YES];
//以下操作不会影响<span style="font-family: Arial, Helvetica, sans-serif;">muArrayCopy</span>
Student *temp = [muArray objectAtIndex:0];
[temp setMName:@"temp"];
[temp.mScore setMChinese:@"12"];
[muArray copy];
[muArray mutableCopy];
[NSMutableArray arrayWithArray:muArray];
三.字典的深浅拷贝(以NSMutableDictionary为例),与二类似
深拷贝
Score *score1 = [[Score alloc] initWithChi:@"11" andEng:@"11"];
Student *stu1 = [[Student alloc] initWithName:@"fufu" andAge:@"10" andScore:score1];
NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
[dic setObject:stu1 forKey:@"key"];
NSMutableDictionary *copyDic = [[NSMutableDictionary alloc]initWithDictionary:dic copyItems:YES];
Student *temp = [dic objectForKey:@"key"];
[temp setMName:@"temp"];
[temp.mScore setMChinese:@"12"];
浅拷贝
[dic copy];
[dic mutableCopy];
[NSMutableDictionary dictionaryWithDictionary:dic];
四.copy与mutableCopy的区别
1.对于Array和Dictory,copy出来的是immutable,mutableCopy出来的是mutable
2.对于自定义的对象,根据需求实现逻辑即可。比如类中有NSString,NSdictory,NSArray等变量,copy和mutable可区于这些变量的copy是mutable与否)
2.对于自定义的对象,根据需求实现逻辑即可。比如类中有NSString,NSdictory,NSArray等变量,copy和mutable可区于这些变量的copy是mutable与否)
NSArray *array = [[NSArray alloc] initWithObjects:@"1",@"2", nil];
NSArray *copyArray = [array copy];
NSMutableArray *mutableCopyArray = [array mutableCopy];
[mutableCopyArray removeObjectAtIndex:0];//正常
NSMutableArray *mutableArray = [[NSMutableArray alloc] initWithObjects:@"1", @"2",nil];
NSMutableArray *copyArray1 = [mutableArray copy];
[copyArray1 removeObjectAtIndex:0];//报错闪退
NSMutableArray *mutableCopyArray1 = [mutableArray mutableCopy];