Objective c 中如何重寫父類的初始化方法

2021-09-07 12:34:08 字數 2854 閱讀 5828

在我們的日常開發中我們經常會定義一些自己的子類繼承一些uikit 庫中的類,那我們應該如何重寫的這些初化方法呢?那我們先看看這些類有哪些初初化方法吧。(這裡就用uiview為例)

- (id)init;

- (nullable instancetype)initwithcoder:(nscoder *)adecoder ns_designated_initializer; - (instancetyp)initwithframe:(cgrect)frame ns_designated_initializer

我們先說說這個幾個方法的執行順序吧,init 方法我們知道它是基類nsobject 類中繼承過來,應該是最基本的方法了,返回乙個自己的物件。initwithcoder 這個是我們用ib初始view來呼叫的。-initwithframe方法呢我們暫時先不說先往下看。

有時候我們經常寫一些的自定義東西我們想把這些東西開源出去,(當然我們很多時候都在用開源東西)。我們就想寫的很完美,我們就會過載所有的初始方法,我們先來定義乙個uiview 子類myview然後重寫這些方法

#import "myview.h"

@implementation myview - (id)initwithframe:(cgrect)frame return self; } - (id)init return self; } - (id)initwithcoder:(nscoder *)adecoder return self; } - (void)setup @end

我們先看看在ib中建立乙個view 把class 設成myview 看看方法的呼叫情況:

我們跑下程式看看輸出情況是不是像我們所說的那樣:

輸出結果是呼叫了 initwithcoder.

所以如果我們想讓我們的類支援ib我們可以重寫這個方法然後初始化一些東西。

下面我們來試試的手動新增的我們先用initwithframe方法:

#import "viewcontroller.h"

#import "myview.h"

@inte***ce viewcontroller () @end @implementation viewcontroller - (void)viewdidload - (void)didreceivememorywarning @end

我們再來執行一下看看結果:

也符合我們的預期。那我們來看看最後一種情況了,因為我們現在的專案中越來越多人採用autolayout了初始化的時候可能呼叫下init就完了。不會去呼叫initwithframe方法,那我們看看我們在重寫了這三個方法後呼叫init初始化會出現什麼情況?我稍加修改一下上面的**:

- (void)viewdidload 

看看輸出結果是什麼?

奇怪了竟然先輸出了initwithframe ,然後才輸出了init 為什麼會這樣子呢?如果你看過我的上篇文章你就應該懂了,我們可以回到最上面看看發現這個兩個方法後面的都有ns_designated_initializer這麼一行字。什麼意思呢?objective-c 有指定初始化方法(designated initializer)和間接(secondary initializer)初始化方法的觀念。 designated 初始化方法是提供所有的引數,secondary 初始化方法是乙個或多個,並且提供乙個或者更多的預設引數來呼叫 designated 初始化的初始化方法。由此我們可以看出init 應該是個secondary initializer 初始方法,當我們呼叫[super init] 時候父類應該是去呼叫designated initializer 方法 initwithframe 方法。所以我們不應該在我們的類裡去重寫secondary initializer 方法。如果像這樣子都重寫了那就會呼叫兩遍我們的setup方法。很顯然這樣子是沒有必要的。同時也會出現問題如果像我們上面那樣的寫法我們就會新增兩個subview到同乙個地方,這顯然不是我們想要的結果所以我們應該避免這樣的情況出現。這裡我打下結果出來的可以自已嘗試下看看:

所以當我們定義乙個子類時:

不需要過載任何初始化函式(當然這個情況不太常用,我們要初始化一些我們自己東西)

過載 designated initializer(上面的我們只要重寫initwithframe 方法即可,如果要支援ib再重寫initwithcoder 就可以了,完全沒有必要再去重寫init 當然你可以只重寫的 init 不重寫initwithframe這樣子也不會出現二次呼叫的問題,但這樣子使用者可以使用initwithframe方法初始化這樣子就會導致一些東西會被沒有初化)

定義乙個新的 designated initializer

如何在Objective C中實現鏈式語法

在接觸到開源專案 masonry 後,裡面的布局約束的鏈式寫法讓我頗感興趣,就像下面這樣 1 2 3 4 5 6 7 8 uiedgeinsets padding uiedgeinsetsmake 10,10,10,10 view1 mas makeconstraints masconstraint...

objective c中命名規範

一 關於objective c中類的命名規範 1 類名 及其 category name 和 protocal name 的首字母大寫,寫使用首字母大寫的形式 分割單詞。駝峰標示 2 在面向特定應用的 中,類名應盡量避免使用字首,每個類都使用相同的字首影響可讀性。3 在面向多應用的 中,推薦使用字首...

Objective C中的快取

nscache可以設定數量限制,通過countlimit與 totalcostlimit來限制cache的數量或者限制cost。當快取的數量超過countlimit,或者cost之和超過totalcostlimit,nscache會自動釋放部分快取。例子如下 可以看到,cache中只保留了最新的30...