在本章中,你将學會
Protocol
協定的使用方法。
前言
和
Apple
官網或者網上分享的教程類文章不同,我将以實際開發角度講述
Swift
語言的一些概念和用法,友善大家更好地學習和掌握
Swift
語言。
這同時也是對自己學習
Swift
語言過程的知識整理。
如有錯誤,以你為準。
項目建立
我們建立一個
SwiftUI
項目,命名為
SwiftUIProtocol
。
協定的定義
協定,規定了用來實作某一特定功能所必需的方法和屬性。
協定提供具體實作來完成協定定義的方法和功能,可以用在
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: "控制流的使用")
]
上述代碼中,我們建立了一個
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)
}
}
}
}
}
協定的建立
上面,我們示範了
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
協定聲明的屬性。
本章代碼
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 = "名稱資訊"