原型模式解决的问题
每个对象需要重新创建
StudentModel *stu1 = [[StudentModel alloc] init];
stu1.name = @"小王";
stu1.age = @(19);
stu1.address = @"中关村";
stu1.totalScore = @(100);
StudentModel *stu2 = [[StudentModel alloc] init];
stu1.name = @"小刘";
stu1.age = @(19);
stu1.address = @"中关村";
stu1.totalScore = @(100);
原型设计:自我拷贝
使用场景:对象创建特别复杂,两个对象在抽象逻辑完全一致,只是在实例化的细节略有差异,如果要重新创建一个对象,不如拷贝自己再去修改
ProtoypeCopyProtocol
@protocol ProtoypeCopyProtocol <NSObject>
@required
- (id)clone;
@end
StudentModel
@interface StudentModel : NSObject <ProtoypeCopyProtocol>
@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSNumber *age;
@property (nonatomic, strong) NSString *address;
@property (nonatomic, strong) NSNumber *totalScore;
- (id)clone;
@end
@implementation StudentModel
- (id)clone {
StudentModel *student = [[[self class] alloc] init];
// 完成复杂操作的所有作业
student.name = self.name;
student.age = self.age;
student.address = self.address;
student.totalScore = self.totalScore;
return student;
}
@end
viewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// 学生1
StudentModel *stu1 = [[StudentModel alloc] init];
stu1.name = @"小王";
stu1.age = @(19);
stu1.address = @"中关村";
stu1.totalScore = @(100);
// 学生2
StudentModel *stu2 = [stu1 clone];
stu2.name = @"小红";
}
框架级别的原型模式:NSCopying
BasCopyObject
//遵循NSCopying协议
@interface BasCopyObject : NSObject <NSCopying>
//子类不要重载这个方法
- (id)copyWithZone:(NSZone *)zone {
.........
BasCopyObject *copyObject = [[self class] allocWithZone:zone];
// 赋值操作作业,//由子类重载实现
[self copyOperationWithObject:copyObject];
return copyObject;
}
- (void)copyOperationWithObject:(id)object {
}
StudentModel
//继承基类
@interface StudentModel : BasCopyObject
- (void)copyOperationWithObject:(StudentModel *)object {
object.name = self.name;
object.age = self.age;
}
ViewController
StudentModel *stu1 = [[StudentModel alloc] init];
StudentModel *stu2 = stu1.copy;
深拷贝与浅拷贝
浅拷贝
ClassModel
- (void)copyOperationWithObject:(ClassModel *)object {
object.className = self.className;
object.students = self.students;
}
ViewController
ClassModel *class1 = [[ClassModel alloc] init];
class1.className = @"班级1";
class1.students = @[stu1, stu2];
ClassModel *class2 = class1.copy;
这样拷贝出来的数组students内存地址一样。说明数组拷贝没有成功。就好像student既属于A班,又属于B班
深拷贝
同时要求数组里的每个对象也要实现NSCopying协议
ClassModel
- (void)copyOperationWithObject:(ClassModel *)object {
object.className = self.className;
// 完成了深拷贝(完整的复制了集合里面的对象)
object.students = [[NSArray alloc] initWithArray:self.students copyItems:YES];
}
ViewController
ClassModel *class1 = [[ClassModel alloc] init];
class1.className = @"班级1";
class1.students = @[stu1, stu2];
ClassModel *class2 = class1.copy;
这样拷贝出来的class2中的数组对象students才能与class1中的数组对象students有不同的内存地址
[self class]
这里使用self,是因为StudentModel可能会被子类继承
StudentModel *student = [[[self class] alloc] init];