[筆記]swift part 5

closure

closure就有如同cobjective-c的block。function其實也可以當作參數一樣傳遞,下面用簡單的範例做練習。

closure的格式如下

1
2
3
{ (parameters) -> returnType in
statements
}

單行的表示式closure可以省略return,參數的部分甚至可以省略寫成$0代表第一個參數,$1代表第二個參數,以此類推,下面用簡單的範例表示

下面這個範例只是單純的介紹寫法而已!

sort這個方法預設是做了升序排列,如果你希望降序排列,可以傳入一個function(closure)進去。

  • 寫法1很單純,傳入已經寫好的function。
  • 寫法2則是將方法名稱、參數、回傳值省略了,並且使用$0表示第一個參數,$1為第二個以以此類推。
  • 寫法3則是把參數也給省略了,直接使用<符號,swift則可以自動幫你推斷要將這兩個參數做<的邏輯。

lazy(懶惰的?緩慢的) with closure

什麼是lazy?,就是當你真的需要使用,才真的會分配(記憶體)給你使用。至於以前objcetive-c的寫法可以參考這篇文章Lazy Initialization with Swift,我覺得她寫很明確,所以我就用我理解的意思大概描述一遍,至於傳統的objective-c的寫法我就不贅述了,畢竟這邊是swift的note。

lazy在swift的使用方式如下

1
2
3

lazy var lazyVar = [String]()

只需要在var前面加上lazy這個keyword,還有一點要注意的是lazy並不能使用let,因為常數在初始化前是必需要有值的。

原本的寫法是@lazy後來修改為lazy,把小老鼠@給省略了。

如果你希望你的變數有會因為一些邏輯判斷而有不同的值,這時可以用closure來完成,下面這段code直接貼在playground是無法使用的,他會告訴你lazy必須是structclass的成員。

1
2
3
4
5
6

lazy var lazyStr:String = {
// do you want
return "This is a test"
}()

在什麼時候你會需要使用使用lazy呢?如果你的變數的值,是需要等到物件初始化完成後才能明確的定義,這時你就會需要使用,下面使用一個簡單的範例;下面範例中可以看到[unowned self],這是要避免strong reference cycle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

class testClass {
var name:String

lazy var sayHiTo:String = {
[unowned self] in
return "Hi~ \(self.name)"
}()

init(name:String) {
self.name = name

}
}

var myClass = testClass(name: "Maya")
// 實立化一個myClass後,這時sayHiTo變數 is nil

myClass.sayHiTo
// 當sayHiTo這個變數被呼叫到才真正的給予值