指定初始化和便利初始化
Posted FarmGuo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指定初始化和便利初始化相关的知识,希望对你有一定的参考价值。
NS_DESIGNATED_INITIALIZER 来声明指定初始化方法
1,指定初始化方法必须调用父类的指定初始化方法(通过super的方式),NSObject是所有类的根类,其指定初始化方法是init。
2,类的便利初始化方法必须调用类的其他指定初始化方法。
3,类实现了指定初始化方法,必须实现(重写)父类的所有指定初始化方法
@interface FGPeople : NSObject
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
- (instancetype)initWithName:(NSString *)name NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithAddress:(NSString *)address;
+ (instancetype)peopleWithName:(NSString *)name;
@end
@interface FGPeople()
@property(nonatomic, copy) NSString *name;
@end
@implementation FGPeople
// 1,指定初始化方法调用父类的指定初始化方法
- (instancetype)initWithName:(NSString *)name
self = [super init];
self.name = name;
return self;
// 2 便利初始化方法调用本类的其他指定初始化方法
- (instancetype)initWithAddress:(NSString *)address
return [self initWithName:address];
// 重写父类的指定初始化方法,因为.h中init后有UNAVAILABLE_ATTRIBUTE标记,所以即使不重写也不会警告,但如果没有标记,不重写就会警告
- (instancetype)init
self = [self initWithName:@"unknow"];
return self;
+ (instancetype)peopleWithName:(NSString *)name
FGPeople *people = [[FGPeople alloc] initWithName:name];
return people;
@end
子类
@interface FGStudent : FGPeople
- (instancetype)initWithGrade:(NSString *)grade NS_DESIGNATED_INITIALIZER;
@end
@interface FGStudent()
@property(nonatomic, copy) NSString *grade;
@end
@implementation FGStudent
// 3 重写父类的指定初始化方法
-(instancetype)initWithName:(NSString *)name
return [self initWithGrade:name];
-(instancetype)initWithGrade:(NSString *)grade
self = [super initWithName:@"unknow"];
self.grade = grade;
return self;
@end
Swift
Swift中有些特殊
1,如果子类中没有任何指定初始化方法,则会继承所有来自父类的指定初始化方法,否则不继承。
2,如果子类提供了所有父类指定构造器的实现,不管是通过 规则 1 继承过来的, 还是通过自定义实现的, 它将自动继承所有父类的便利构造器。
4,如果子类实现了父类的所有指定初始化方法,不管是继承还是自定义的,则子类会继承父类的所有便利初始化方法。
1,Swift的指定初始化方法,必须在本类的属性已经确定后,才调用父类的指定初始化方法,
2,Swift继承自父类的属性不能在调用父类的指定初始化方法之前赋值(会被覆盖)。
3,便利初始化方法中,属性的赋值只能在调用指定初始化方法后进行。
4,对属性的读,实例方法的调用必须在初始化方法调用后才能进行。
链接
https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
以上是关于指定初始化和便利初始化的主要内容,如果未能解决你的问题,请参考以下文章
swift5.x 类初始化反初始化, 指定初始化器,便利初始化器