1、使用自定义初始化器
-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender;
-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender{
if (self = [super init]) {
//进行赋值操作
self.userId = userId;
.....
}
return self;
}
使用自定义初始化器会有很长的方法名,并且加入更多属性时不会向下兼容。
但也领使用新版模型的应用能在编译时知道了什么地方发生了改变。
2、使用生成器模式
//构建一个生成器
#import <Foundation/Foundation.h>
NS_ASSUME_NONNULL_BEGIN
//@class防止互相引用,死循环
@class User;
@interface UserBuilder : NSObject
@property (nonatomic , copy) NSString *userId;
@property (nonatomic , copy) NSString *firstName;
@property (nonatomic , copy) NSString *lastName;
@property (nonatomic , copy) NSString *gender;
- (User *)build;
//构建对象,一个例子
//用生成器构建的对象
-(User *)createUser;
@end
NS_ASSUME_NONNULL_END
#import "UserBuilder.h"
#import "User.h"
@implementation UserBuilder
//build方法实现
-(User *)build{
return [[User alloc]initWithUserBuilder:self];
}
//构建对象,一个例子
-(User *)createUser{
User *user = [User userWithBlock:^( UserBuilder *builder ) {
builder.userId = @"001";
builder.firstName = @"First";
builder.lastName = @"Last";
builder.gender = @"F";
}];
return user;
}
@end
#import <Foundation/Foundation.h>
@class UserBuilder;
NS_ASSUME_NONNULL_BEGIN
@interface User : NSObject
@property (nonatomic , copy) NSString *userId;
@property (nonatomic , copy) NSString *firstName;
@property (nonatomic , copy) NSString *lastName;
@property (nonatomic , copy) NSString *gender;
//模型提供的类方法
+(instancetype)userWithBlock:(void(^)(UserBuilder *))block;
//模型的私有扩展--自定义初始化器
-(instancetype)initWithUserBuilder:(UserBuilder *)builder;
//-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender;
@end
NS_ASSUME_NONNULL_END
#import "User.h"
#import "UserBuilder.h"
@implementation User
//模型自定义初始化
-(instancetype)initWithUserBuilder:(UserBuilder *)builder{
if (self = [super init]) {
self.userId = builder.userId;
self.firstName = builder.firstName;
self.lastName = builder.lastName;
self.gender = builder.gender;
}
return self;
}
//方法实现
+(instancetype)userWithBlock:(void (^)(UserBuilder * _Nonnull))block{
UserBuilder *builder = [[UserBuilder alloc]init];
block(builder);
return [builder build];
}
//-(instancetype)initWithUserId:(NSString *)userId firstname:(NSString *)firstName lastName:(NSString *)lastName gender:(NSString *)gender{
// if (self = [super init]) {
// //进行赋值操作
// self.userId = userId;
// .....
// }
// return self;
//}
@end
//内部核心构建模型
UserBuilder *builder = [[UserBuilder alloc]init];
User *u = [builder createUser];
//调用者使用build方法构建模型
builder.userId = @"000";
builder.firstName = @"name";
builder.lastName = @"last";
builder.gender = @"AAA";
User *builderUser =[builder build];
优点
模型总是向下兼容的,新版模型生成器包含了新的属性,不会破话createUser的代码,
生成器可以直接创建,调用者也可以初始化生成器,并且调用build方法创建模型对象
生成器的创建和处理可以留给内部核心完成。模型调用者可以使用userWithBlock:,无需初始化或亲自调用build方法
Tips:头文件互相引用问题(头文件导入循环引用)
引入头文件的时机尽量延后,只有在有需要的地方才引用,这样就可以减少类所需引入头文件的数量,使用向前声明,如果要编译A类,编译器就要知道B类文件,但是要编译B,则需要知道A,这样就会导致循环引用。
此时就需要使用@class+类文件,这样只是声明了这个名称是类的名称。至于是如何定义的编译器不需要完全知道。
然后在.m中import,import就会包含这个类的所有信息,包括实体变量和方法。