协议
属性协议
我们可以在协议中定义属性,下面的代码就是毛病的,由于协议中定义了只读属性,但是却尝试修改其值:
protocol FullyNamed {
var fullName: String { get }
}
struct Person: FullyNamed{
var fullName: String
}
let john = Person(fullName: "WHY")
john.fullName = "WHY"
协议合成
1个协议可由多个协议采取 protocol<SomeProtocol, AnotherProtocol>
这样的格式进行组合,称为协议合成(protocol composition)。
protocol Named {
var name: String { get }
}
protocol Aged {
var age: Int { get }
}
struct Person: Named, Aged {
var name: String
var age: Int
}
func wishHappyBirthday(celebrator: protocol<Named, Aged>) {
println("Happy birthday (celebrator.name) - you're (celebrator.age)!")
}
let birthdayPerson = Person(name: "Malcolm", age: 21)
wishHappyBirthday(birthdayPerson)
协议实战
我们来设计1个计数器,实战练习1下协议相干的内容。
首先先定义1个协议,CounterDataSource
,这个协议提供了增量值,也就是说,计数器每次计数增加的数值。这个值可以是1个固定值,比如每次增1,也能够是个方法,根据不同情况返回不同的增量值。所以我们的定义以下:
@objc protocol CounterDataSource {
optional func incrementForCount(count: Int) -> Int
optional var fixedIncrement: Int { get }
}
@objc
表示协议是可选的,也能够用来表示暴露给Objective-C的代码,只对类有效。
接下来我们来定义1个计数器,这个计数器里有1个 CounterDataSource
类型的数据源。有点像是UITableViewDataSource
的感觉,我们通过这个协议来获得这1次计数增加的步长。如果 dataSource
实现了incrementForCount
方法,那末就通过这个方法来获得步长,否则看看能不能通过固定值获得步长:
@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
}
}
}
可以先用固定值的方法计数:
class ThreeSource: CounterDataSource {
let fixedIncrement = 3
}
var counter = Counter()
counter.dataSource = ThreeSource()
for _ in 1...4 {
counter.increment()
println(counter.count)
}
也能够用方法来计数:
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)
}
最近时间有限,简单浏览了1下官方文档。以后遇到了再补充吧。
References