天天看點

Swift實用小冊20: Protocol協定的使用

在本章中,你将學會​

​Protocol​

​協定的使用方法。

前言

和​

​Apple​

​​官網或者網上分享的教程類文章不同,我将以實際開發角度講述​

​Swift​

​​語言的一些概念和用法,友善大家更好地學習和掌握​

​Swift​

​語言。

這同時也是對自己學習​

​Swift​

​語言過程的知識整理。

如有錯誤,以你為準。

項目建立

我們建立一個​

​SwiftUI​

​​項目,命名為​

​SwiftUIProtocol​

​。

Swift實用小冊20: Protocol協定的使用

協定的定義

協定,規定了用來實作某一特定功能所必需的方法和屬性。

協定提供具體實作來完成協定定義的方法和功能,可以用在​

​class​

​​類、​

​Struct​

​​結構體、​

​enum​

​枚舉類型上,我們一般叫做某某“遵循”什麼協定。

協定的示例

在​

​Swift​

​​開發過程中,我們常常會使用到​

​MVC、MVVM​

​​開發模式,其中​

​Model​

​部分,常常伴随着協定的定義。示例:

import SwiftUI

struct Model: Identifiable {
    var id = UUID()
    var title: String
    var placehoder: String
}

var Models = [
    Model(title: "基礎部分", placehoder: "常量和變量的使用"),
    Model(title: "基礎運算符", placehoder: "基礎運算符的使用"),
    Model(title: "字元串和字元", placehoder: "字元串的使用"),
    Model(title: "集合類型", placehoder: "集合類型的使用"),
    Model(title: "控制流", placehoder: "控制流的使用")
]      
Swift實用小冊20: Protocol協定的使用

上述代碼中,我們建立了一個​

​Model​

​​結構體,它遵循​

​Identifiable​

​協定。

​Identifiable​

​協定,可以為類或值類型提供穩定的身份概念,這樣我們就可以在​

​View​

​​視圖中使用由​

​UUID()​

​​确定的​

​唯一id​

​的資料。

我們聲明了​

​3​

​​個變量:​

​id、title、placehoder​

​​,然後建立了一個數組變量​

​Models​

​并賦予了一些示例資料。

由于我們​

​Model​

​​結構體遵循​

​Identifiable​

​​協定,是以哪怕我們數組​

​Models​

​​内的資料是完全一樣的,由于​

​Identifiable​

​協定保證在對象的生存期内保持唯一,它也會被系統定義為​

​2條​

​。

我們在​

​View​

​​視圖中使用​

​List​

​​清單和​

​ForEach​

​循環周遊數組資料,示例:

struct ContentView: View {
    var body: some View {
        List {
            ForEach(Models) { Model in
                HStack {

                    Text(Model.title)
                        .font(.system(size: 17))

                    Spacer()

                    Text(Model.placehoder)
                        .font(.system(size: 14))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}      
Swift實用小冊20: Protocol協定的使用

協定的建立

上面,我們示範了​

​Identifiable​

​​協定的作用,在​

​Swift​

​​開發過程中,我們使用最多的也是官方提供的協定,像​

​Identifiable​

​​協定,​

​Codable​

​​協定,​

​Hashable​

​協定。

如果我們需要建立協定,需要使用到​

​protocol​

​​關鍵字,建立協定的方式和​

​class​

​​類、​

​struct​

​結構體建立方式類似。示例:

protocol Person {
    func addPerson()
}      

上述代碼中,我們建立了一個​

​Person​

​​協定,在​

​Person​

​協定内我們定義了一個方法。

使用​

​Person​

​協定的方式和子類繼承父類的方式相同,但是:

繼承隻能繼承一個父類,而類或者結構體可以遵循多個協定。

示例:

struct FullName: Person {
    func addPerson() {
        print("實作協定方法")
    }
}      

我們建立了一個​

​FullName​

​​結構體,遵循​

​Person​

​​協定,然後在​

​FullName​

​​結構體中使用​

​addPerson​

​方法。

協定的屬性

協定用于指定特定的執行個體屬性或類屬性,而不用指定是存儲型屬性或計算型屬性,此外還必須指明是隻讀的還是可讀可寫的。

協定的屬性有兩種:可讀可寫屬性,隻讀屬性。

可讀可寫屬性:{ set get }

隻讀屬性:{ get }

使用協定的屬性的方法和聲明計算屬性或存儲屬性類似,隻是後面需要加上關鍵字。示例:

protocol Person2 {
    var present: Bool { get }
    var message: String { get set }
}

struct FullName2: Person2 {
    var present: Bool = true
    var message: String = "名稱資訊"      

上述代碼中,我們建立了一個​

​Person2​

​​協定,它有​

​2​

​​個變量屬性:​

​present​

​​、​

​message​

​​,其中​

​present​

​​是隻讀屬性,​

​message​

​是可讀可寫屬性。

然後,我們建立了一個結構體​

​FullName2​

​​,遵循​

​Person2​

​​協定。我們就可以直接使用使用​

​Person2​

​協定聲明的屬性。

Swift實用小冊20: Protocol協定的使用

本章代碼

import SwiftUI

struct Model: Identifiable {
    var id = UUID()
    var title: String
    var placehoder: String
}

var Models = [    Model(title: "基礎部分", placehoder: "常量和變量的使用"),    Model(title: "基礎運算符", placehoder: "基礎運算符的使用"),    Model(title: "字元串和字元", placehoder: "字元串的使用"),    Model(title: "集合類型", placehoder: "集合類型的使用"),    Model(title: "控制流", placehoder: "控制流的使用")]

struct ContentView: View {
    var body: some View {
        List {
            ForEach(Models) { Model in
                HStack {
                    Text(Model.title)
                        .font(.system(size: 17))

                    Spacer()

                    Text(Model.placehoder)
                        .font(.system(size: 14))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

protocol Person {
    func addPerson()
}

struct FullName: Person {
    func addPerson() {
        print("實作協定方法")
    }
}

protocol Person2 {
    var present: Bool { get }
    var message: String { get set }
}

struct FullName2: Person2 {
    var present: Bool = true
    var message: String = "名稱資訊"