Swift可選協議要求
可選協議要求
可選協議含有可選成員,其遵循者
可以選擇是否實現這些成員。在協議中使用@optional
關鍵字作為前綴來定義可選成員。
可選協議在調用時使用可選鏈
,詳細內容在可選鏈章節中查看。
像someOptionalMethod?(someArgument)
一樣,你可以在可選方法名稱後加上?
來檢查該方法是否被實現。可選方法
和可選屬性
都會返回一個可選值(optional value)
,當其不可訪問時,?
之後語句不會執行,並返回nil
。
注意: 可選協議隻能在含有@objc
前綴的協議中生效。且@objc
的協議隻能被類
遵循。
Counter
類使用CounterDataSource
類型的外部數據源來提供增量值(increment amount)
,如下所示:
@objc protocol CounterDataSource {
@optional func incrementForCount(count: Int) -> Int
@optional var fixedIncrement: Int { get }
}
CounterDataSource
含有incrementForCount
的可選方法
和fiexdIncrement
的可選屬性
。
注意:CounterDataSource
中的屬性和方法都是可選的,因此可以在類中聲明但不實現這些成員,儘管技術上允許這樣做,不過最好不要這樣寫。
Counter
類含有CounterDataSource?
類型的可選屬性dataSource
,如下所示:
@objc class Counter {
var count = 0
var dataSource: CounterDataSource?
func increment() {
if let amount = dataSource?.incrementForCount?(count) {
count += amount
} else if let amount = dataSource?.fixedIncrement? {
count += amount
}
}
}
count
屬性用於存儲當前的值,increment
方法用來為count
賦值。
increment
方法通過可選鏈
,嘗試從兩種可選成員
中獲取count
。
-
由於
dataSource
可能為nil
,因此在dataSource
後邊加上了?
標記來表明隻在dataSource
非空時才去調用incrementForCount`方法。 -
即使
dataSource
存在,但是也無法保證其是否實現了incrementForCount
方法,因此在incrementForCount
方法後邊也加有?
標記。
在調用incrementForCount
方法後,Int
型可選值
通過可選綁定(optional binding)
自動拆包並賦值給常量amount
。
當incrementForCount
不能被調用時,嘗試使用可選屬性``fixedIncrement
來代替。
ThreeSource
實現了CounterDataSource
協議,如下所示:
class ThreeSource: CounterDataSource {
let fixedIncrement = 3
}
使用ThreeSource
作為數據源開實例化一個Counter
:
var counter = Counter()
counter.dataSource = ThreeSource()
for _ in 1...4 {
counter.increment()
println(counter.count)
}
// 3
// 6
// 9
// 12
TowardsZeroSource
實現了CounterDataSource
協議中的incrementForCount
方法,如下所示:
class TowardsZeroSource: CounterDataSource {
func incrementForCount(count: Int) -> Int {
if count == 0 {
return 0
} else if count < 0 {
return 1
} else {
return -1
}
}
}
下邊是執行的代碼:
counter.count = -4
counter.dataSource = TowardsZeroSource()
for _ in 1...5 {
counter.increment()
println(counter.count)
}
// -3
// -2
// -1
// 0
// 0