Swift 3 基礎 — Initializer

BoShi Lee 
4 min readMar 6, 2017

當一個物件在初始化的當下可以順便帶入, 該物件該有的變數,以便建立物件,在一個 class 在初始化時便會呼叫 init() 這一個 function,利用 init() 賦予 class 後續的 code 運行所需的所有變數初始值。

例如有一個 class Dog:

class Dog { }

你可透過下列 code 製作一個 Dog instance

Dog()

但上述的 code 沒有太大用處因為,因為你沒有給他一個參考位置,所以你在建立完之後馬上就又消失不見,xcode 會希望你給他一個存放位置。

所以我們給了他一個參考位置存放:

let dog = Dog()

如此一來,Dog 這個 class 被建立了起來並存放在 dog ,我們可以透過 dog. 來取得這個 class 底下的所有公開資訊。

你可以觀察到一點,在你建立這個 dog 你可以發現到 Dog() 使用了圓括號 (),代表這你建立的同時呼叫了隱含初始化 (implicit initializer)init()

這個 init() 是系統預設的,讓你方便的初始化這個 class 當你沒有建立自訂的 Initializer 時,他便會自動的呼叫這個 init()

Custom Initializers

上述的 Dog() 裡面並沒有放入任何的變數,在一般的開發環境中,我們會習慣在一個 class 放入一至多個變數,讓 class 裡的任何 function 可以運用這些變數。

我們在這個 Dog() 裡加入了兩個變數,並加入 Initializers。

接下來你就可以依照不同的情境下去使用這些 Initializer:

但你不能再繼續使用:

let dog = Dog()

原因是當你一旦建立了自定義的 Initializer 之後,這個 init() 便不存在這個 class 裡了,你可以透過明確的定義 explict Initializer 來建立。

如此一來,又可以使用這個 init() 了。

我們可以不需要把每一個初始化都寫成一個,事實上,我們只需要寫一個 initializer 即可!

可以寫成這樣的原因是,initializer 其實就是一個特別的 function,而 function 本質上是可以在參數定義自己的初始值的,而我們這樣做的同時,原本的定義出來的實體還是可以繼續使用。

更有趣的一點是,initializer 定義出來之後,就可以在上面的變數定義時,不需要直接傳入任何值,只需要定義變數的 type 即可。

請注意一點,在 swift 中每一個變數都需要一個初始值,跟 objc 有很大的差異,所以以下是一個錯誤的初始化方式:

你可以在一開始定義時使用常數 constants let ,原因是因為 initializer,就是專門為變數或常數設定初始值。

在實際的應用上,這樣子做的意義是,我們希望呼叫這個 class 的時候 ”必須“ 帶入所有包含的參數。

Optional properties

思考一下,在某些情境的使用上,可能會遇到在初始化的時候,沒有辦法馬上帶入應有的參數時改怎麼辦呢?

  1. 使用預設值

2. 使用 optional warped
還記得 optional 的宣告其實是宣告一個 Optional(type) 嗎?
我們可以利用這個特點將 name 定義成 一個 unwarped optional String String!

因此這一個變數就有了解包可選字串,等到真正要傳入變數時才在傳入,這樣在後續的 code 可以直接地去使用,如下列範例:

Referring to self

所有的 properties 在 class 還沒賦予初始值之前,class 都無法被使用,直到所有 properties 都有初始值:

上面中的 bark() 其實是隱含了 self.bark() ,在所有的 properties 都有直之前都不能使用 class 裡的 func,必須把 bark() 往下移動一行,才能做使用。

Failable initializer

initializer 可以是可以失敗的,當某些帶入的直沒有達到特定的條件時,class 將沒有辦法初始化,要使用可失敗的 initializer 必須在 init 加入 ? 如下:

返回一個 nil 代表這個 class 沒有被建立,也就是說無論這個 class 可以被建立與否,他都是一個 optional(type),代表著要使用這個實體都必須 unwarped。

--

--