上午忙著一個新項目上線的問題,中午吃飯也挺晚。吃完飯回來睡了一會,所以中午沒有學swift。 下午從3點開始,看到5點,晚上又看了很久。
今天看了不少,到第173頁。
swift引入的不確定類型(?),總覺得有點太過復雜,把原來許多挺好理解的東西都搞的四不像的。
還有類的構造過程,引入便利構造器,還有可失敗構造器,以及一系列默認構造器,再配合以繼承,真的太臃腫而繁瑣。感覺下個版本,構造函數這里肯定要大改。
今天發現了一個官方做app的教程,看了一點,很不錯,有swift的,xcode的,還有ui設計的,很容易讓人快速進入app開發。挺不錯的,看完swift就看這個教程吧。
筆記如下:
1 可失敗構造器。如果一個類,結構體或者枚舉,在構造自身的過程中有可能失敗,則定義為一個可失敗的構造器,語法為init?。
注: 可失敗構造器的參數名和參數類型,不能與其他非可失敗構造器的參數名及類型相同。
構造失敗,返回nil。
例如:
struct Animal {
let species: String
init?(species: String?) {
if ((species == nil)
|| (species!.isEmpty)){
return nil
} else {
self.species = species!
}
}
}
//返回可選類型 Animal?
let animal = Animal.init(species: "")
帶原始值的枚舉類型會自帶一個可失敗構造器init?(rawValue:)。
2 你可以用子類的可失敗構造器覆蓋父類的可失敗構造器,你也可以用子類的非可失敗構造器覆蓋一個基類的可失敗構造器。
注:一個非可失敗構造器永遠也不能代理調用一個可失敗構造器。你可以用一個非可失敗構造器覆蓋一個可失敗構造器,反過來卻不行。
在構造器前加required關鍵字來保證該類的所有子類都必須實現該構造器。當子類在覆蓋父類的required構造器時,必須同樣加required關鍵字,無需加override關鍵字。
3 使用閉包或全局函數初始化存儲屬性。
struct Checkerboard {
let boardColors: [Bool] = {
var temporaryBoard = [Bool]()
var isBlack = false
for i in 1...10 {
for j in 1...10 {
temporaryBoard.append(isBlack)
isBlack = !isBlack
}
}
return temporaryBoard
}() //()很關鍵
}
var checkrboard = Checkerboard()
4 析構,swift的析構函數通過deinit定義。不允許主動調用自己的析構函數,
swift通過引用計數的方式來進行gc,所以觸發deinit的方式,可以簡單的將該引用設置為nil。
class Persion {
var name: String
init(name: String = "sigh") {
self.name = name
print("hi \(name)")
}
deinit {
print("bye bye")
}
}
var p1: Persion? = Persion()
var p2: Persion? = p1
p1 = nil
p2 = nil //觸發析構
5 閉包循環引用。
class HtmlElement {
let name: String
let text: String?
//在默認的閉包中可以使用self,因為只有在初始化完成,且self確實存在時,才能訪問lazy屬性
lazy var asHtml: ()-> String = {
var res: String
if let text = self.text {
res = "<\(self.name)>\(text)</\(self.name)>"
} else {
res = "<\(self.name)/>"
}
return res
}
init(name: String, text: String? = nil) {
self.name = name
self.text = text
}
}
var htmlElement = HtmlElement(name: "hello")
print(htmlElement.asHtml())
在閉包中使用了self,強引用了類,而類也強引用了閉包。
swift對于循環引用的解決方案,引入弱引用和無主引用的方式,感覺也是有點偷懶的設計,完全可以在編譯層面解決這個問題,而不是說把這些暴露給用戶。
明天繼續看吧。
這周目標200頁,問題應該不大。