Swift 系統學習 27 閉包的使用

//: Playground - noun: a place where people can play

import UIKit

/*
 * 本節主要內容:
 * 1.閉包的使用
 */

// 不使用
var array: [Int] = []
for _ in 0..<10 {
    array.append(Int(arc4random()%100))
}

array
func biggerNumber(first: Int, second: Int) -> Bool {
    return first > second
}
array.sort(by: biggerNumber)

// 使用閉包
/*
 * 優勢: 直接, 不需要單獨聲明函數
 * 缺點: 重用性不太好
 */
array.sorted { (first: Int, second: Int) -> Bool in
    return first > second
}
// 簡化形式
array.sorted { (first, second) -> Bool in
    return first > second
}
// 簡化形式
array.sorted{ first, second -> Bool in
    return first > second }

array.sorted{ first, second in
    return first > second }

// 推薦方式: $0, $1, $2 ......
array.sorted{ return $0 > $1 }
array

// 不推薦: >是方法
array.sorted(by: >)



//: Playground - noun: a place where people can play

import UIKit

// 課堂練習一:
struct Person {
    let name: String
    let age: Int
}

class PersonView {
    var name: String?
    var age: String?
    
    enum InputError: Error {
        case InputMissing // 輸入爲空
        case AgeIncorrect // 年齡輸入不是整型
    }
    
    // 自定義方法
    func createPerson() throws -> Person {
        guard let age = age, let name = name, name.characters.count > 0 && age.characters.count > 0 else {
            throw InputError.InputMissing
        }
        
        guard let ageFormatted = Int(age) else {
            throw InputError.AgeIncorrect
        }
        
        return Person(name: name, age: ageFormatted)
    }
}
// 實例化
var personView = PersonView()
// 模擬用戶從界面上輸入
personView.age = "21"
personView.name = "Shirley"
do {
    let person = try personView.createPerson()
    print("Success! Person created. \(person)")
} catch PersonView.InputError.InputMissing {
    print("Input Missing")
} catch PersonView.InputError.AgeIncorrect {
    print("Something went wrong, please try again!")
}

// 課堂練習二:
class Album {
    var name: String // 專輯名字
    
    init(name: String) {
        self.name = name
    }
    func getPerformance() -> String {
        return "The album \(name) sold lots."
    }
}

class StudioAlbum: Album {
    var studio: String
    
    init(name: String, studio: String) {
        self.studio = studio
        super.init(name: name)
    }
    
    override func getPerformance() -> String {
        return "The studio album \(name) sold lots."
    }
}

class LiveAlbum: Album {
    var location: String // 現場位置
    
    init(name: String, location: String) {
        self.location = location
        super.init(name: name)
    }
    
    override func getPerformance() -> String {
        return "The live album \(name) sold lots."
    }
}

// 實例化
var taylorSwift = StudioAlbum(name: "Taylor Swift", studio: "The Castles Studios")
var fearless = StudioAlbum(name: "Avril Lavigne", studio: "The Canadian Studio")
var iTunesLive = LiveAlbum(name: "Linkin Park Live", location: "New York")

// 數組
var allAlbums: [Album] = [taylorSwift, fearless, iTunesLive]

for album in allAlbums {
    print(album.getPerformance())
}





Day06

回顧:
1. init
   1.1 目的: 創建對象(結構體/類) + 屬性進行初始化
   1.2 要求: init + 沒有返回值 + 參數個數沒有要求
   1.3 init?本質: 創建對象返回該類型的可選型
        —> 解包
   
2. subscript下標語法:
   2.1 目的: 獲取類型(枚舉/結構體/類)的屬性
   2.2 方式: 像從集合類(數組/字典/集合)中獲取元素的值
   2.3 語法: 函數和計算型屬性結合
        subscript(index: Int) -> Int {
             get { }
             set { }
        }
       // 結果:
       matric[0] -> 結構體第一個屬性
       matric[1] -> 結構體第二個屬性 ……..

3. computed property計算型屬性和stored property存儲屬性
    3.1 計算型屬性: 指定set/get
    3.2 存儲屬性: 存儲某種類型的值
    3.3 var center: Point2D {
               get { return xxxx }
               set { newValue關鍵詞 }
          }
    3.3 只讀屬性
          var center: Point2D {
               return xxxx
          }

4. error handling(*****)
   4.1 第一階段:
       enum VendingMachineError: Error {
           case OutOfStock
           case NotEnoughMoney
           // ………
       }
  4.2 第二階段:
       func functionName(param: paramType) throws -> returnType {
           // 針對不同的錯誤, 拋出不同的error
           throw  VendingMachineError.OutOfStock
       }
  4.3 第三階段:
       a. var result = try! functionName(varName)
       b. var result = try? functionName(varName)
       c. 完整形式: 處理錯誤
          do {
                var result = try functionName(varName)
          } catch  VendingMachineError.OutOfStock {
               print(“Out of stock”)
          } catch {
                print(“There is the error.”)
          }

今天內容:
	·	 類基本聲明和實例化
	·	 類屬性分類: 存儲屬性/計算型屬性/類屬性/延遲加載屬性
	·	 類繼承
	·	 類訪問限制

類基本聲明和實例化
1. 在Swift語言中, 類可以沒有繼承
2. 樣例: 類的聲明和實例化
    [ 01_basic_class ]
    —> 存儲屬性(可選型) + init + init? + 自定義方法

/05_Swift/Day06/Day06-AM1.zip

3. 類的各種屬性: 存儲屬性 / 計算型屬性 / 類型屬性 / 延遲加載屬性
    [ 02_class_property ]
    3.1 存儲屬性: 使用”屬性觀察器”機制, 對存儲屬性值的變化做出觀察和相應的反應(willSet: 將要賦值 / didSet: 賦值完 ).
     —>  UInt8.max = 255
    3.2 計算型屬性: get set
  —> 問題? 存儲屬性和計算型屬性獲取方式?
        a. 先實例化對象, 再通過點語法
        b. 存儲屬性和計算型屬性作用在實例對象上
    3.3 類型屬性(Type Property): 作用在該類型上的屬性
   —> 例如: 獲取方式
         a. 結構體: 結構體名字.類型屬性名字
         b. 類: 類名字.類型屬性名字
    —> 適用場景:
         a. 登陸用戶 —> 實例對象; 分數: 
         b. 記錄所有玩家最高分 -> 類型屬性
    3.4 延遲加載屬性 -> 懶加載屬性
    —> 適用場景: 
         a. 依賴於其他屬性的值先初始化
         b. 屬性的計算特別耗時, 不希望在實例化階段計算

/05_Swift/Day06/Day06-AM2.zip

———————— 下午內容 ————
1. 樣例: 延遲存儲屬性(Lazy Stored Property): 
     [ 03_lazy_property ]
   —> 在初始化階段(init), 不被賦值; 
   —> 直到使用/創建的時候才被賦值, 且賦值一次
   —> 延遲存儲屬性沒有”屬性觀察器”語法

2. Swift語言中類的繼承/封裝/多態
   2.1 封裝 / 繼承(單繼承; 沒有父類) / 多態
   2.2 樣例: 聲明多個類, 繼承關係
        [ 04_class_inheritance ]
     —> 總結:
        a. override
        b. final

/05_Swift/Day06/Day06-AM2.zip

3. 閉包Closure: 
   3.1 三種表現形式:
       全局函數; 嵌套函數(可以捕獲上下文所有常量和變量); 閉包表達式(匿名函數語法)
   3.2 閉包表達式語法:
        { (參數列表) -> 返回類型 in
            表達式
        }
       —> 對比函數聲明
       func functionName(參數列表) -> 返回類型 {
             表達式
       }
   3.3 樣例: 閉包的使用
       [ 05_closure ]

 課堂練習一: 
  [ 06_practice ]
 1).聲明類(視圖), 添加兩個屬性(登錄名字和年齡; 可選型),自定義方法(創建Person結構體對象)
 2).聲明結構體Person(模型)(登錄名字和年齡)
 3).要求: 使用Error Handling錯誤處理機制, 處理下面幾種情況
   a. 名字和年齡輸入爲空
   b. 輸入的年齡不符合格式(只能是整型類型)
 4).驗證Error Handling錯誤機制的實現

包括課堂練習一:
/05_Swift/Day06/Day06-PM2.zip

 課堂練習二:
 [ 06_practice ]
 1). 創建三個類,父類是描述專輯類Album, 兩個子類, 分別描述錄音室專輯類StudioAlbum和現場版專輯LiveAlbum
 2).父類: 專輯名字(屬性), init, 自定義方法(返回字符串: 反應銷售情況)
 3).StudioAlbum: 錄音室名字(屬性), init, 重寫父類的自定義方法
 4).LiveAlbum: 現場名字(屬性); init, 重寫父類的自定義方法
 5).聲明數組, 元素類型Album, 元素的值是實例化對象, 循環打印每個對象的屬性的值

WWDC樣例代碼鏈接:
https://developer.apple.com/sample-code/wwdc/


Day06知識點總結:
1. 掌握存儲屬性觀察器, 延遲加載屬性的使用和適用場景
2. 掌握類的重寫override和final機制
3. 掌握閉包表達式語法














發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章