From caed8e20afec3fe4f1b1a561970f88c12599f179 Mon Sep 17 00:00:00 2001 From: oldcodeoberyn Date: Sun, 31 Aug 2014 22:17:22 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=8D=8F=E8=AE=AE?= =?UTF-8?q?=E4=B8=80=E7=AB=A0=EF=BC=8C=E6=B7=BB=E5=8A=A0=E6=96=B0=E7=9A=84?= =?UTF-8?q?=E4=B8=A4=E4=B8=AA=E5=B0=8F=E8=8A=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Initializer requirement Class-only protocol --- source/chapter2/21_Protocols.md | 75 ++++++++++++++++++++++++++++++++- 1 file changed, 74 insertions(+), 1 deletion(-) diff --git a/source/chapter2/21_Protocols.md b/source/chapter2/21_Protocols.md index b8ffb090..8e52d694 100755 --- a/source/chapter2/21_Protocols.md +++ b/source/chapter2/21_Protocols.md @@ -9,13 +9,15 @@ - [协议的语法(Protocol Syntax)](#protocol_syntax) - [对属性的规定(Property Requirements)](#property_requirements) - [对方法的规定(Method Requirements)](#method_requirements) -- [对突变方法的的规定(Mutating Method Requirements)](#mutating_method_requirements) +- [对突变方法的规定(Mutating Method Requirements)](#mutating_method_requirements) +- [对构造器的规定(Initializer Requirements)](#initializer_requirements) - [协议类型(Protocols as Types)](#protocols_as_types) - [委托(代理)模式(Delegation)](#delegation) - [在扩展中添加协议成员(Adding Protocol Conformance with an Extension)](#adding_protocol_conformance_with_an_extension) - [通过扩展补充协议声明(Declaring Protocol Adoption with an Extension)](#declaring_protocol_adoption_with_an_extension) - [集合中的协议类型(Collections of Protocol Types)](#collections_of_protocol_types) - [协议的继承(Protocol Inheritance)](#protocol_inheritance) +- [类专属协议(Class-Only Protocol)](#class_only_protocol) - [协议合成(Protocol Composition)](#protocol_composition) - [检验协议的一致性(Checking for Protocol Conformance)](#checking_for_protocol_conformance) - [对可选协议的规定(Optional Protocol Requirements)](#optional_protocol_requirements) @@ -208,6 +210,60 @@ lightSwitch.toggle() //lightSwitch 现在的值为 .On ``` + +## 对构造器的规定 + +协议可以要求它的遵循类型实现特定的构造器。你可以像书写普通的构造器那样,在协议的定义里写下构造器的需求,但不需要写花括号和构造器的实体: + +```swift +protocol SomeProtocol { + init(someParameter: Int) +} +``` + +**协议构造器规定在类中的实现** + +你可以在协议的遵循类中把协议构造器规定实现为指定构造器或者便利构造器。在这两种情况下,你都必须给构造器实现标上"required"修饰符: + +```swift +class SomeClass: SomeProtocol { + required init(someParameter: Int) { + //构造器实现 + } +} +``` + +使用`required`修饰符可以保证:所有的遵循该协议的子类,同样能为构造器规定提供一个显式的实现或继承实现。 + +关于`required`构造器的更多内容,请参考`required`构造器 + +>注意 +> +>如果类已经被“final”修饰符所标示,你就不需要在协议构造器规定的实现中使用"required"修饰符。因为final类不能有子类。关于`final`修饰符的更多内容,请参见防止重写 + +如果一个子类重写了父类的指定构造器,并且该构造器遵循了某个协议的规定,那么该构造器的实现需要被同时标示`required`和`override`修饰符 + +```swift +protocol SomeProtocol { + init() +} + + +class SomeSuperClass { + init() { + //协议定义 + } +} + + +class SomeSubClass: SomeSuperClass, SomeProtocol { + // "required" from SomeProtocol conformance; "override" from SomeSuperClass + required override init() { + // 构造器实现 + } +} +``` + ## 协议类型 @@ -524,6 +580,23 @@ println(game.asPrettyText()) // ○ ○ ▲ ○ ○ ▲ ○ ○ ▲ ▲ ○ ○ ○ ▼ ○ ○ ○ ○ ▼ ○ ○ ▼ ○ ▼ ○ ``` + +## 类专属协议 +你可以在协议的继承列表中,通过添加“class”关键字,限制协议只能适配到类(class)类型。(结构体或枚举不能遵循该协议)。该“class”关键字必须是第一个出现在协议的继承列表中,其后,才是其他继承协议。 + +```swift +protocol SomeClassOnlyProtocol: class, SomeInheritedProtocol { + // class-only protocol definition goes here +} +``` +在以上例子中,协议SomeClassOnlyProtocol只能被类(class)类型适配。如果尝试让结构体或枚举类型适配该协议,则会出现编译错误。 + +>注意 +> +>当协议需求定义的行为,要求(或假设)它的遵循类型必须是引用语义而非值语义时,应该采用类专属协议。关于引用语义,值语义的更多内容,请查看结构体和枚举是值类型类是引用类型 + + + ## 协议合成 From a15a35bfa710a1c285e987e2db5af08861fe3847 Mon Sep 17 00:00:00 2001 From: oldcodeoberyn Date: Thu, 4 Sep 2014 21:43:31 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0beta6=E7=9A=84=E9=83=A8?= =?UTF-8?q?=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit beta6 断言现在可以使用字符串内插语法 beta6 字符串和字符的链接方式发生变化 beta6 属性声明章节 新增availably属性(部分,剩下的2014.9.5更新) --- source/chapter2/01_The_Basics.md | 6 +-- source/chapter2/03_Strings_and_Characters.md | 25 ++++++------ source/chapter2/21_Protocols.md | 2 +- source/chapter3/06_Attributes.md | 42 ++++++++++++++++++++ 4 files changed, 58 insertions(+), 17 deletions(-) diff --git a/source/chapter2/01_The_Basics.md b/source/chapter2/01_The_Basics.md index 6d71bbaa..27333623 100755 --- a/source/chapter2/01_The_Basics.md +++ b/source/chapter2/01_The_Basics.md @@ -657,7 +657,7 @@ if let definiteString = assumedString { ## 断言 -可选类型可以让你判断值是否存在,你可以在代码中优雅地处理值缺失的情况。然而,在某些情况下,如果值缺失或者值并不满足特定的条件,你的代码可能并不需要继续执行。这时,你可以在你的代码中触发一个_断言(assertion)_来结束代码运行并通过调试来找到值缺失的原因。 +可选类型可以让你判断值是否存在,你可以在代码中优雅地处理值缺失的情况。然而,在某些情况下,如果值缺失或者值并不满足特定的条件,你的代码可能没办法继续执行。这时,你可以在你的代码中触发一个_断言(assertion)_来结束代码运行并通过调试来找到值缺失的原因。 ### 使用断言进行调试 @@ -673,9 +673,9 @@ assert(age >= 0, "A person's age cannot be less than zero") // 因为 age < 0,所以断言会触发 ``` -在这个例子中,只有`age >= 0`为`true`的时候代码运行才会继续,也就是说,当`age`的值非负的时候。如果`age`的值是负数,就像代码中那样,`age >= 0`为`false`,断言被触发,结束应用。 +在这个例子中,只有`age >= 0`为`true`的时候,即`age`的值非负的时候,代码运行才会继续。如果`age`的值是负数,就像代码中那样,`age >= 0`为`false`,断言被触发,结束应用。 -断言信息不能使用字符串插值。断言信息可以省略,就像这样: +断言信息如果不需要,可以被省略,就像这样: ```swift assert(age >= 0) diff --git a/source/chapter2/03_Strings_and_Characters.md b/source/chapter2/03_Strings_and_Characters.md index 0cca5497..3bc1b248 100755 --- a/source/chapter2/03_Strings_and_Characters.md +++ b/source/chapter2/03_Strings_and_Characters.md @@ -167,30 +167,29 @@ println("unusualMenagerie has \(countElements(unusualMenagerie)) characters") ## 连接字符串和字符 (Concatenating Strings and Characters) -字符串和字符的值可以通过加法运算符(`+`)相加在一起并创建一个新的字符串值: +字符串可以通过加法运算符(`+`)相加在一起(或称“串联”)并创建一个新的字符串: ```swift let string1 = "hello" let string2 = " there" -let character1: Character = "!" -let character2: Character = "?" - -let stringPlusCharacter = string1 + character1 // 等于 "hello!" -let stringPlusString = string1 + string2 // 等于 "hello there" -let characterPlusString = character1 + string1 // 等于 "!hello" -let characterPlusCharacter = character1 + character2 // 等于 "!?" +var welcome = string1 + string2 +// welcome 现在等于 "hello there" ``` -您也可以通过加法赋值运算符 (`+=`) 将一个字符串或者字符添加到一个已经存在字符串变量上: +您也可以通过加法赋值运算符 (`+=`) 将一个字符串添加到一个已经存在字符串变量上: ```swift var instruction = "look over" instruction += string2 -// instruction 现在等于 "look over there" +// instruction 现在等于 "look over there" -var welcome = "good morning" -welcome += character1 -// welcome 现在等于 "good morning!" +``` +你可以用将`append`方法将一个字符附加到一个字符串变量的尾部: + +```swift +let exclamationMark: Character = "!" +welcome.append(exclamationMark) +// welcome 现在等于 "hello there!" ``` > 注意: diff --git a/source/chapter2/21_Protocols.md b/source/chapter2/21_Protocols.md index 8e52d694..ad0bcaa4 100755 --- a/source/chapter2/21_Protocols.md +++ b/source/chapter2/21_Protocols.md @@ -223,7 +223,7 @@ protocol SomeProtocol { **协议构造器规定在类中的实现** -你可以在协议的遵循类中把协议构造器规定实现为指定构造器或者便利构造器。在这两种情况下,你都必须给构造器实现标上"required"修饰符: +你可以在遵循该协议的类中实现构造器,并指定其为类的特定构造器或者便捷构造器。在这两种情况下,你都必须给构造器实现标上"required"修饰符: ```swift class SomeClass: SomeProtocol { diff --git a/source/chapter3/06_Attributes.md b/source/chapter3/06_Attributes.md index fbf2e64f..0b200cac 100755 --- a/source/chapter3/06_Attributes.md +++ b/source/chapter3/06_Attributes.md @@ -23,6 +23,48 @@ 声明特性只能应用于声明。然而,你也可以将`noreturn`特性应用于函数或方法类型。 +`availability` + + +将`availability`特性用于声明时,将表示该声明的生命周期会依赖于特定的平台和操作系统版本。 + +`availability`特性总会与参数列表一同出现,该参数列表至少有两个参数,参数之间由逗号分隔。第一个参数由以下这些平台名字中的一个起头:iOS, iOSApplicationExtension, OSX, or OSXApplicationExtension。当然,你也可以用一个星号(*)来表示,该声明在上面提到的所有平台上都是有效的。剩下的参数,可以以任何顺序出现,并且可以附加关于声明生命周期的附加信息,包括重要的里程碑。 + + +- `unavailable`参数表示该声明在特定的平台上是无效的 + + + +- `introduced`参数表示:特定的平台上,该声明被使用的第一个版本。格式如下:

`introduced=version number`

这个version number由一个正的十进制整数或浮点数构成。 + + +- `deprecated`参数表示:特定的平台上,该声明被建议弃用的第一个版本。格式如下: +

`deprecated=version number`

这个version number由一个正的十进制整数或浮点数构成。 + + +- `obsoleted`参数表示:特定的平台上,该声明被弃用的第一个版本。格式如下: +

`deprecated=version number`

这个version number由一个正的十进制整数或浮点数构成。 + +The message argument is used to provide a textual message that’s displayed by the compiler when emitting a warning or error about the use of a deprecated or obsoleted declaration. It has the following form: +message=message +The message consists of a string literal. +The renamed argument is used to provide a textual message that indicates the new name for a declaration that’s been renamed. The new name is displayed by the compiler when emitting an error about the use of a renamed declaration. It has the following form: +renamed=new name +The new name consists of a string literal. +You can use the renamed argument in conjunction with the unavailable argument and a type alias declaration to indicate to clients of your code that a declaration has been renamed. For example, this is useful when the name of a declaration is changed between releases of a framework or library. +// First release +protocol MyProtocol { + // protocol definition +} +// Subsequent release renames MyProtocol +protocol MyRenamedProtocol { + // protocol definition +} + +@availability(*, unavailable, renamed="MyRenamedProtocol") +typealias MyProtocol = MyRenamedProtocol +You can apply multiple availability attributes on a single declaration to specify the declaration’s availability on different platforms. The compiler uses an availability attribute only when the attribute specifies a platform that matches the current target platform. + `assignment` 该特性用于修饰重载了复合赋值运算符的函数。重载了复合赋值运算符的函数必需将它们的初始输入参数标记为`inout`。如何使用`assignment`特性的一个例子,请见:[复合赋值运算符]()。