(十六) [OC高效系列]提供"全能初始化方法"

1.什么是全能初始化方法?

提供必要信息的初始化方法。

2.先搞一個(gè)例子

@interface YXRectangle : NSObject
@property (nonatomic,readonly) float width;
@property (nonatomic,readonly) float height;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
@end

@implementation YXRectangle
//全能初始化方法
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height
{
    self = [super init];
    if (self) {
        _width = width;
        _height = height;
    }
    return self;
}
@end

- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height這個(gè)方法就是全能初始化方法。其他的初始化方法都應(yīng)該調(diào)用這個(gè)方法來創(chuàng)建對(duì)象。

3.所以我們還要至少要復(fù)寫已經(jīng)有的初始化方法,比如init方法

@interface YXRectangle : NSObject
@property (nonatomic,readonly) float width;
@property (nonatomic,readonly) float height;
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height;
@end
@implementation YXRectangle
- (instancetype)init{
    return [self initWithWidth:500 height:500];
}
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height
{
    self = [super init];
    if (self) {
        _width = width;
        _height = height;
    }
    return self;
}
@end

這樣不管使用者怎么創(chuàng)建都能通過這個(gè)全能初始化方法正常創(chuàng)建。

4.那他的子類也一個(gè)全能初始化方法,而且要調(diào)用父類的全能初始化方法,以維系調(diào)用鏈。

比如我們創(chuàng)建一個(gè)正方形的子類YXSquare

@interface YXSquare : YXRectangle

- (instancetype)initWithDimension:(CGFloat)dimension;
@end

@implementation YXSquare
- (instancetype)initWithDimension:(CGFloat)dimension
{
   return  [super initWithWidth:dimension height:dimension];
}
@end

5.但是如果使用者繼續(xù)使用父類的全能初始化方法呢,這樣就有可能出現(xiàn)寬高不等的正方形。

所以還應(yīng)該阻止使用者直接調(diào)用父類的全能初始化方法

@interface YXSquare : YXRectangle
- (instancetype)initWithDimension:(CGFloat)dimension;
@end

@implementation YXSquare
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height{
    @throw  [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must be use initWithDimension :instead" userInfo:nil];
}
- (instancetype)initWithDimension:(CGFloat)dimension
{
   return  [super initWithWidth:dimension height:dimension];
}
@end

6.如果使用者還是用init來創(chuàng)建呢,這樣還是調(diào)用父類中的init方法,還是有可能出現(xiàn)長(zhǎng)寬不等的情況,所以還應(yīng)該復(fù)寫一下init方法


@interface YXSquare : YXRectangle
- (instancetype)initWithDimension:(CGFloat)dimension;
@end
@implementation YXSquare
- (instancetype)initWithWidth:(CGFloat)width height:(CGFloat)height{
    @throw  [NSException exceptionWithName:NSInternalInconsistencyException reason:@"Must be use initWithDimension :instead" userInfo:nil];
}
- (instancetype)initWithDimension:(CGFloat)dimension
{
   return  [super initWithWidth:dimension height:dimension];
}
-(instancetype)init{
    return [self initWithDimension:500];
}
@end

7.如果有兩種全能初始化方法呢?比如UIView,有從code中加載的全能初始化方法initWithCoder之類的。

覆寫它,然后在其中調(diào)用父類的全能初始化方法。

8.總結(jié)

  • 在類中提供一個(gè)全能初始化方法,并于文檔中說明,其他方法都應(yīng)該調(diào)用此方法
  • 若全能初始化方法與父類不同,則需覆寫超類中的對(duì)應(yīng)方法
  • 如果超類的初始化方法不適用于子類,那么應(yīng)該覆寫這個(gè)超類的方法,并在其中拋出異常
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容