update 02/04

This commit is contained in:
numbbbbb
2014-06-10 15:52:22 +08:00
parent 49c28ff603
commit b5bf26fee7
44 changed files with 1473 additions and 320 deletions

View File

@ -11,20 +11,20 @@
protocol SomeProtocol {
// 协议内容
}
`类`,`结构体`,`枚举`的名称后加上`协议名称`,中间以冒号`:`分隔即可实现协议;实现多个协议时,各协议之间用逗号`,`分隔,如下所示:
struct SomeStructure: FirstProtocol, AnotherProtocol {
// 结构体内容
}
当某个类含有`父类`的同时并实现了协议,应当把`父类`放在所有的`协议`之前,如下所示:
class SomeClass: SomeSuperClass, FirstProtocol, AnotherProtocol {
// 类的内容
}
## 属性要求
`协议`能够要求其`遵循者`必须含有一些**特定名称和类型**的`实例属性(instance property)``类属性 (type property)`,也能够要求属性的`(设置权限)settable``(访问权限)gettable`,但它不要求`属性``存储型属性(stored property)`还是`计算型属性(calculate property)`.
@ -35,17 +35,17 @@
var musBeSettable : Int { get set }
var doesNotNeedToBeSettable: Int { get }
}
`类`来实现`协议`时,使用`class`关键字来表示该属性为类成员;用`结构体``枚举`实现`协议`时,则使用`static`关键字来表示:
protocol AnotherProtocol {
class var someTypeProperty: Int { get set }
}
protocol FullyNamed {
var fullName: String { get }
}
}
`FullyNamed`协议含有`fullName`属性.因此其`遵循者`必须含有一个名为`fullName`,类型为`String`的可读属性.
struct Person: FullyNamed{
@ -53,11 +53,11 @@
}
let john = Person(fullName: "John Appleseed")
//john.fullName 为 "John Appleseed"
`Person`结构体含有一个名为`fullName``存储型属性`,完整的`遵循`了协议.(*若协议未被完整遵循,编译时则会报错*).
`Person`结构体含有一个名为`fullName``存储型属性`,完整的`遵循`了协议.(*若协议未被完整遵循,编译时则会报错*).
如下所示,`Startship``遵循``FullyNamed`协议:
class Starship: FullyNamed {
var prefix: String?
var name: String
@ -71,7 +71,7 @@
}
var ncc1701 = Starship(name: "Enterprise", prefix: "USS")
// ncc1701.fullName == "USS Enterprise"
`Starship`类将`fullName`实现为可读的`计算型属性`.它的每一个实例都有一个名为`name`的必备属性和一个名为`prefix`的可选属性. 当`prefix`存在时,将`prefix`插入到`name`之前来为`Starship`构建`fullName`
## 方法要求
@ -85,11 +85,11 @@
protocol SomeProtocol {
class func someTypeMethod()
}
protocol RandomNumberGenerator {
func random() -> Double
}
`RandomNumberGenerator`协议要求其`遵循者`必须拥有一个名为`random`, 返回值类型为`Double`的实例方法. (我们假设随机数在[0,1]区间内).
`LinearCongruentialGenerator``遵循``RandomNumberGenerator`协议,并提供了一个叫做*线性同余生成器(linear congruential generator)*的伪随机数算法.
@ -109,7 +109,7 @@
// 输出 : "Here's a random number: 0.37464991998171"
println("And another one: \(generator.random())")
// 输出 : "And another one: 0.729023776863283"
## 突变方法要求
能在`方法``函数`内部改变实例类型的方法称为`突变方法`.在`值类型(Value Type)`(*译者注:特指结构体和枚举*)中的的`函数`前缀加上`mutating`关键字来表示该函数允许改变该实例和其属性的类型. 这一变换过程在[Modifyting Value Types from Within Instance Methods](1)章节中有详细描述.
@ -123,7 +123,7 @@
protocol Togglable {
mutating func toggle()
}
当使用`枚举``结构体`来实现`Togglabl`协议时,必须在`toggle`方法前加上`mutating`关键字.
如下所示,`OnOffSwitch`枚举`遵循``Togglable`协议,`On`,`Off`两个成员用于表示当前状态
@ -148,7 +148,7 @@
`协议`本身不实现任何功能,但你可以将它当做`类型`来使用.
使用场景:
使用场景:
* 作为函数,方法或构造器中的参数类型,返回值类型
* 作为常量,变量,属性的类型
@ -159,7 +159,7 @@
class Dice {
let sides: Int
let generator: RandomNumberGenerator
init(sides: Int, generator: RandomNumberGenerator) {
init(sides: Int, generator: RandomNumberGenerator) {
self.sides = sides
self.generator = generator
}
@ -188,7 +188,7 @@
//Random dice roll is 4
//Random dice roll is 5
//Random dice roll is 4
## 委托(代理)模式
委托是一种设计模式(*译者注: 想起了那年 UITableViewDelegate 中的奔跑,那是我逝去的Objective-C...*),它允许`类``结构体`将一些需要它们负责的功能`交由(委托)`给其他的类型.
@ -197,7 +197,7 @@
委托模式可以用来响应特定的动作或接收外部数据源提供的数据,而无需要知道外部数据源的类型.
下文是两个基于骰子游戏的协议:
下文是两个基于骰子游戏的协议:
protocol DiceGame {
var dice: Dice { get }
@ -208,9 +208,9 @@
func game(game: DiceGame, didStartNewTurnWithDiceRoll diceRoll:Int)
func gameDidEnd(game: DiceGame)
}
`DiceGame`协议可以在任意含有骰子的游戏中实现,`DiceGameDelegate`协议可以用来追踪`DiceGame`的游戏过程
如下所示,`SnakesAndLadders``Snakes and Ladders`(译者注:[Control Flow](2)章节有该游戏的详细介绍)游戏的新版本.新版本使用`Dice`作为骰子,并且实现了`DiceGame``DiceGameDelegate`协议
class SnakesAndLadders: DiceGame {
@ -235,7 +235,7 @@
break gameLoop
case let newSquare where newSquare > finalSquare:
continue gameLoop
default:
default:
square += diceRoll
square += board[square]
}
@ -243,7 +243,7 @@
delegate?.gameDIdEnd(self)
}
}
游戏的`初始化设置(setup)`被为`SnakesAndLadders`类的`构造器(initializer)`实现.所有的游戏逻辑被转移到了`play`方法中.
> 注意:因为`delegate`并不是该游戏的必备条件,`delegate`被定义为遵循`DiceGameDelegate`协议的可选属性
@ -301,7 +301,7 @@
protocol TextRepresentable {
func asText() -> String
}
通过`扩展`为上一节中提到的`Dice`类遵循`TextRepresentable`协议
extension Dice: TextRepresentable {
@ -309,7 +309,7 @@
return "A \(sides)-sided dice"
}
}
从现在起,`Dice`类型的实例可被当作`TextRepresentable`类型:
let d12 = Dice(sides: 12,generator: LinearCongruentialGenerator())
@ -334,7 +334,7 @@
var name: String
func asText() -> String {
return "A hamster named \(name)"
}
}
}
extension Hamster: TextRepresentabl {}
@ -375,7 +375,7 @@
如下所示,`PrettyTextRepresentable`协议继承了`TextRepresentable`协议
protocol PrettyTextRepresentable: TextRepresentable {
func asPrettyText() -> String
func asPrettyText() -> String
}
`遵循``PrettyTextRepresentable`协议的同时,也需要`遵循`TextRepresentable`协议.
@ -444,9 +444,9 @@
使用`is`检验协议一致性,使用`as`将协议类型`向下转换(downcast)`为的其他协议类型.检验与转换的语法和之前相同(*详情查看[Typy Casting章节](5)*):
* `is`操作符用来检查实例是否`遵循`了某个`协议`.
* `is`操作符用来检查实例是否`遵循`了某个`协议`.
* `as?`返回一个可选值,当实例`遵循`协议时,返回该协议类型;否则返回`nil`
* `as`用以强制向下转型.
* `as`用以强制向下转型.
@objc protocol HasArea {
var area: Double { get }
@ -538,7 +538,7 @@
`count`属性用于存储当前的值,`increment`方法用来为`count`赋值.
`increment`方法通过`可选链`,尝试从两种`可选成员`中获取`count`.
1. 由于`dataSource`可能为`nil`,因此在`dataSource`后边加上了`?`标记来表明只在`dataSource`非空时才去调用incrementForCount`方法.
2. 即使`dataSource`存在,但是也无法保证其是否实现了`incrementForCount`方法,因此在`incrementForCount`方法后边也加有`?`标记