From ef92f7e3672a1b5984c8cd629bc1415e492ec467 Mon Sep 17 00:00:00 2001 From: mr-tyrion Date: Mon, 11 Aug 2014 18:01:31 +0800 Subject: [PATCH] =?UTF-8?q?1=EF=BC=89=E4=BF=AE=E6=AD=A3=E4=BA=86=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E9=A1=B5=E9=9D=A2=E7=9A=84=E9=94=99?= =?UTF-8?q?=E8=AF=AF=202=EF=BC=89=E5=A2=9E=E5=8A=A0=E4=BA=86=E8=8B=B9?= =?UTF-8?q?=E6=9E=9Cblog=E7=BF=BB=E8=AF=91=E7=9A=84=E6=96=87=E7=AB=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- index.html | 8 +- source/SUMMARY.md | 2 + source/chapter1/03_revision_history.md | 2 + source/chapter4/01_Access_Control.md | 84 ++++++++ source/chapter4/02_Type_Custom.md | 273 +++++++++++++++++++++++++ source/chapter4/chapter4.md | 0 6 files changed, 368 insertions(+), 1 deletion(-) create mode 100644 source/chapter4/01_Access_Control.md create mode 100644 source/chapter4/02_Type_Custom.md create mode 100644 source/chapter4/chapter4.md diff --git a/index.html b/index.html index f4d0df27..4026a6f9 100644 --- a/index.html +++ b/index.html @@ -8,6 +8,12 @@ - + + + + diff --git a/source/SUMMARY.md b/source/SUMMARY.md index a523bd0a..d92a7fe5 100755 --- a/source/SUMMARY.md +++ b/source/SUMMARY.md @@ -39,4 +39,6 @@ * [模式](chapter3/07_Patterns.md) * [泛型参数](chapter3/08_Generic_Parameters_and_Arguments.md) * [语法总结](chapter3/09_Summary_of_the_Grammar.md) +* [苹果官方Blog官方翻译](chapter4/chapter4.md) + * [Access Control 权限控制的黑与白](chapter4/01_Access_Control.md) diff --git a/source/chapter1/03_revision_history.md b/source/chapter1/03_revision_history.md index 8e60b062..f8d22075 100644 --- a/source/chapter1/03_revision_history.md +++ b/source/chapter1/03_revision_history.md @@ -9,9 +9,11 @@ - [XCode6 Beta5 Swift语法文档更新](#xcode6_beta5) - [XCode6 Beta4 Swift语法文档更新](#xcode6_beta4) +- XCode6下载: [老码云盘下载](http://pan.baidu.com/disk/home#from=share_pan_logo&path=%252F%25E8%2580%2581%25E7%25A0%2581%25E4%25BA%2591%25E7%259B%2598-XCode6%252FXCode6-Beta5) 以下部分是针对XCode6每一次Beta版本直至正式版发布,Swift语法部分的更新归类 + # XCode6 Beta5中Swift语法更新 diff --git a/source/chapter4/01_Access_Control.md b/source/chapter4/01_Access_Control.md new file mode 100644 index 00000000..d046aede --- /dev/null +++ b/source/chapter4/01_Access_Control.md @@ -0,0 +1,84 @@ +> 翻译:[老码团队翻译组-Arya](http://weibo.com/littlekok/) +> 校对:[老码团队翻译组-Oberyn](http://weibo.com/u/5241713117) + +# Access Control 权限控制的黑与白 + +如果您之前没有接触过权限控制,先来听一个小故事: + +> 小明是五道口工业学院的一个大一新生,最近他有点烦恼,因为同屋经常用他的热水壶,好像那是自己家的一样,可是碍于同学情面,又不好意思说。直到有一天,他和学姐小K吐槽。 + +> 学姐听了之后,说:大学集体生活里面,大部分东西都是默认室友可以共用的。如果你不想别人拿,我可以帮你做封印,只要打上private标记,它们就看不到你的东西,更加用不了你的东西了。 + +> 小明说哇靠学姐你还会妖法...... + + +Swift语言从Xcode 6 beta 5版本起,加入了对权限控制(Access Control)的支持。其实权限控制和小明的物品一样,你可以设定水壶是只有自己能用,还是只有宿舍里的人能用,还是全校都可以用。 + +从此以后,你可以好像神盾局局长一样,完全掌控自己的代码块的”保密级别“,哪些是只能在本文件引用,哪些能用在整个项目里,你还可以发挥大爱精神,把它开源成只要导入你的框架,大家都可以使用的API。 + +这三种权限分别是: + +- #####private 私有的 + + 在哪里写的,就在哪里用。无论是类、变量、常量还是函数,一旦被标记为私有的,就只能在定义他们的源文件里使用,不能为别的文件所用。 + +- #####internal 内部的 + + 标记为internal的代码块,在整个应用(App bundle)或者框架(framework)的范围内都是可以访问的。 + +- #####public 公开的 + + 标记为public的代码块一般用来建立API,这是最开放的权限,使得任何人只要导入这个模块,都可以访问使用。 + + +如果要把所有的爱加上一个期限,噢不,是给所有的代码块都标记上权限,不累死才怪。还好swift里面所有代码实体的默认权限,都是最常用的internal。所以当你开发自己的App时,可能完全不用管权限控制的事情。 + +但当你需要写一个公开API的时候,就必须对里面的代码块进行“隐身对其可见”的public标记,要么其他人是用不到的。 + +Private(私有级别)的权限最严格,它可以用来隐藏某些功能的细节实现方式。合理构筑你的代码,你就可以安全地使用extension和高级功能,又不把它们暴露给项目内的其他文件。 + +除了可以给整个声明设权限,Swift还允许大家在需要的时候,把某个属性(property)的取值权限比赋值权限设得更加开放。 + +#####举个例子: + + public class ListItem { + + // ListItem这个类,有两个公开的属性 + public var text: String + public var isComplete: Bool + + // 下面的代码表示把变量UUID的赋值权限设为private,对整个app可读,但值只能在本文件里写入 + private(set) var UUID: NSUUID + + public init(text: String, completed: Bool, UUID: NSUUID) { + self.text = text + self.isComplete = completed + self.UUID = UUID + } + + // 这段没有特别标记权限,因此属于默认的internal级别。在框架目标内可用,但对于其他目标不可用 + func refreshIdentity() { + self.UUID = NSUUID() + } + + public override func isEqual(object: AnyObject?) -> Bool { + if let item = object as? ListItem { + return self.UUID == item.UUID + } + return false + } + } + + +当我们使用Objective-C和Swift混合开发时,需要注意: + +- 如果你在写的是一个应用,Xcode会生成一个头文件来保证两者的可互访性,而这个生成的头文件会包含public和internal级别的声明。 + +- 如果你的最终产品是一个Swift框架,头文件里只会出现标记为public级别的声明。(因为框架的头文件,属于公开的Objective-C接口的一部分,只有public部分对Objective-C可用。) + +虽然Swift不推荐大家传播和使用第三方的框架,但对于建立和分享源文件形式的框架是支持的。对于需要写框架,方便应用与多个项目的开发者来说,要记得把API标记为public级别。 + +如果您想了解更多关于权限控制的内容,可以查看苹果官方最新的《The Swift Language》和《Using Swift with Cocoa and Objective-C》指南, +这两本指南在iBooks里面可以下载更新喔。 + +本文由翻译自Apple Swift Blog :https://developer.apple.com/swift/blog/?id=5 diff --git a/source/chapter4/02_Type_Custom.md b/source/chapter4/02_Type_Custom.md new file mode 100644 index 00000000..0c1ada34 --- /dev/null +++ b/source/chapter4/02_Type_Custom.md @@ -0,0 +1,273 @@ +> 翻译:[老码团队翻译组-Tyrion](http://weibo.com/u/5241713117) +> 校对:[老码团队翻译组-Oberyn](http://weibo.com/u/5241713117) + +# 造个类型不是梦-白话Swift类型创建 +----------------- + +本页包含内容: + +- [自定义原型](#prototype) +- [实现默认值](#imp-default) +- [支持基本布尔型初始化](#init-by-bool) +- [支持Bool类型判断](#condition-by-bool) +- [支持兼容各们各派的类型](#support-all-type) +- [完善OCBool的布尔基因体系](#make-up-type) + +小伙伴们,Swift中的Bool类型有着非常重要的语法功能,并支撑起了整个Swift体系中的逻辑判断体系,经过老码的研究和学习, Bool类型本身其实是对基础Boolean类型封装,小伙伴们可能咬着手指头问老码,怎么一会Bool类型,一会Boolean类型,其区别在于,前者是基于枚举的组合类型,而后者则是基本类型,只有两种true和false。 + + +####自定义原型 +接下老码根据Bool的思想来创建一个OCBool类型,来让小伙伴们了解一下Swift中到底是怎么玩儿的。 +来我们先看一下OCBool的定义。 + +#####代码示例如下: + 1. enum OCBool{ + 2. case ocTrue + 3. case ocFalse + 4. } + +#####注意: + +- 代码中第2行和第3行,可以合并到一行写,如苹果官方Blog所写的一样 +- 代码中命名需要注意:OCBool是类型名,所以首字母必须大写,而case中的ocTrue和ocFalse是小类型则需要首字母小写。 + + +####实现默认值 +行,我们给了一个漂亮的定义,不过按照传统语言的经验,Bool值默认情况下是假, 所以我们的OCBool也应该如此,我们使用类型扩展技术增加这个默认特性: + + 1. extension OCBool{ + 2. init(){ + 3. self =.ocFalse + 4. } + 5. } + +#####注意: +- 代码中第1行:extension关键字,非常强大,小伙伴们可以通过此创造出许多好玩的东西,建议各位去Github上看一个名为“Swiftz”的项目,它将扩展用到了极致。 +- 代码中第3行:self = .ocFalse语法,刚入门的小伙伴们很迷糊,为什么会有奇怪的点语法,因为大牛Chris在Swift中增加了类型智能推断功能,在苹果Blog中,提到了“Context”概念,就是这个意思,因为这行语句是在枚举OCBool中的,其上下文就是OCBool的定义体,编译器当然知道.ocFalse就是OCBool.ocFalse了,所以这里直接点语法,非常整齐。 +现在我们可以使用如下方法使用这个Bool类型。 + +#####代码示例如下: + + 1. var result:OCBool = OCBool() + 2. var result1:OCBool = .ocTrue + + +####支持基本布尔型初始化 +正如上述代码所述,我们只能通过类型或者枚举项目赋值,这是组合类型的用法,但是编码的日子里,我们总是希望和true,false直接打交道,也就是说,我们希望这么做, +代码示例如下: + + 1. var isSuccess:OCBool = true + +如果小伙伴们直接这么用,则会出现如下错误: + + 1. /Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/main.swift:30:24: Type 'OCBool' does not conform to protocol 'BooleanLiteralConvertible' + +编译器咆哮的原因是,我们的类型没有遵从“布尔字面量转换协议”,接下来修正这个问题, +#####代码示例如下: + + 1. import Foundation + 2. + 3. println("Hello, World!") + 4. + 5. enum OCBool{ + 6. case ocTrue + 7. case ocFalse + 8. } + 9. + 10. + 11. extension OCBool: BooleanLiteralConvertible{ + 12. static func convertFromBooleanLiteral( value: Bool) ->OCBool{ + 13. return value ? ocTrue : ocFalse + 14. } + 15. } + 16. + 17. var isSuccess:OCBool = true + +#####注意: +- 代码中的第11行是重点,我的类型OCBool支持了BooleanLiteralConvertible协议,这个协到底是干什么的呢,小伙伴们在Xcode代码编辑器,按住Command键,然后点击第11行中的BooleanLiteralConvertible协议名,则会进入它的定义, +#####其定义如下: + + 1. protocol BooleanLiteralConvertible { + 2. typealias BooleanLiteralType + 3. class func convertFromBooleanLiteral(value: BooleanLiteralType) -> Self + 4. } + +- 这个定义中有个类方法convertFromBooleanLiteral,它的参数为BooleanLiteralType类型,也就是我传入的Bool类型, 且返回值为实现这个协议的类型本身,在我们的OCBool类型中,其返回值就是OCBool本身。经过这个定义,我们可以直接对OCBool类型直接进行布尔字面量初始化了。 + + +####支持Bool类型判断 +小伙伴们不安分, 肯定想着我怎么用它实现逻辑判断,所以如果你这么写, +#####代码示例如下: + + 1. var isSuccess:OCBool = true + 2. + 3. if isSuccess { + 4. println( "老码请你吃火锅!") + 5. } + +你永远吃不到老码的火锅,因为这里编译器会咆哮: + + 1. /Users/tyrion-OldCoder/Documents/Learning/BoolType/BoolType/main.swift:27:4: Type 'OCBool' does not conform to protocol 'LogicValue' + +OCBool现在只能用bool类型初始化,而不能直接返回bool型,小火把们还记得在《老码说编程之白话Swift江湖》中,老码多次提到,妈妈再也不担心我们 if a = 1{}的写法了, 因为等号不支持值返回了, 所以在if判断是后面的条件必须有返回值,OCBool没有,所以编译器哭了。我们解决这个问题。 + +#####代码示例如下: + + 1. import Foundation + 2. + 3. println("Hello, World!") + 4. + 5. enum OCBool{ + 6. case ocTrue + 7. case ocFalse + 8. } + 9. + 10. + 11. extension OCBool: BooleanLiteralConvertible{ + 12. static func convertFromBooleanLiteral( value: Bool) ->OCBool{ + 13. return value ? ocTrue : ocFalse + 14. } + 15. } + 16. + 17. extension OCBool: LogicValue{ + 18. func getLogicValue() ->Bool { + 19. var boolValue: Bool{ + 20. switch self{ + 21. case .ocTrue: + 22. return true + 23. case .ocFalse: + 24. return false + 25. } + 26. } + 27. return boolValue + 28. } + 29. } + 30. + 31. + 32. var isSuccess:OCBool = true + 33. + 34. if isSuccess { + 35. println( "老码请你吃火锅!") + 36. } + +####运行结果如下: + + 1. Hello, World! + 2. 老码请你吃火锅! + 3. Program ended with exit code: 0 + +#####注意: +- 如果小伙伴们现在用的是Beta版的Xcode,注意苹果官方Blog中,在代码第17行如果在Xcode Beta4下是错误的,这里的协议是,LogicValue而不是BooleanVue,所以记得看错误提示才是好习惯。 +- 注意代码第34行,完美支持if判断,且输出结果为“老码请你吃火锅”,老码也是说说而已,请不要当真。 + + +####支持兼容各们各派的类型 +小伙伴们,江湖风险,门派众多,老码有自己的OCBool类型,可能嵩山少林有自己的SSBool类型,甚至连郭美美都可能有自己的MMBool类型,所以OCBool必须能够识别这些类型,这些各门各派的类型,只要支持LogicValue协议,就应该可以被识别,看老码怎么做, + +#####代码示例如下: + + 1. extension OCBool{ + 2. init( _ v: LogicValue ) + 3. { + 4. if v.getLogicValue(){ + 5. self = .ocTrue + 6. } + 7. else{ + 8. self = .ocFalse + 9. } + 10. } + 11. + 12. } + 13. + 14. var mmResult: Bool = true + 15. var ocResult:OCBool = OCBool(mmResult) + 16. + 17. + 18. if ocResult { + 19. println( "老码没钱,郭美美请你吃火锅!") + 20. } + +#####代码运行结果如下: + + 1. Hello, World! + 2. 老码没钱,郭美美请你吃火锅! + 3. Program ended with exit code: 0 + +漂亮!我们的OCBool类型现在支持了所有的逻辑变量初始化。 + +#####注意: +- 代码中第2行:“_”下横杠的用法,这是一个功能强大的小强,在此的目的是屏蔽外部参数名,所以小伙伴们可以直接:var ocResult:OCBool = OCBool(mmResult)而不是:var ocResult:OCBool = OCBool(v: mmResult),小伙伴们惊呆了!这个init函数中本来就没有外部参数名啊,还记得老码在书里说过没,Swift的初始化函数会默认使用内部参数名,作为外部参数名。 + + +####完善OCBool的布尔基因体系: +小伙伴们,bool类型的价值就是在于各种判断,诸如==,!=, &,|,^,!,以及各种组合逻辑运算,我们OCBool也要具备这些功能,否则就会基因缺陷,且看老码如何实现: + + 1. extension OCBool: Equatable{ + 2. } + 3. + 4. //支持等值判断运算符 + 5. func ==( left: OCBool, right: OCBool )->Bool{ + 6. switch (left, right){ + 7. case (.ocTrue, .ocTrue): + 8. return true + 9. default: + 10. return false + 11. } + 12. } + 13. //支持位与运算符 + 14. func &( left:OCBool, right: OCBool)->OCBool{ + 15. + 16. if left{ + 17. return right + 18. } + 19. else{ + 20. return false + 21. } + 22. } + 23. //支持位或运算符 + 24. func |( left:OCBool, right: OCBool)->OCBool{ + 25. + 26. if left{ + 27. return true + 28. } + 29. else{ + 30. return right + 31. } + 32. } + 33. + 34. //支持位异或运算符 + 35. func ^( left:OCBool, right: OCBool)->OCBool{ + 36. return OCBool( left != right ) + 37. } + 38. //支持求反运算符 + 39. @prefix func !( a:OCBool )-> OCBool{ + 40. return a ^ true + 41. } + 42. //支持组合求与运算符 + 43. func &= (inout left:OCBool, right:OCBool ){ + 44. left = left & right + 45. } + 46. + 47. + 48. var isHasMoney:OCBool = true + 49. var isHasWife:OCBool = true + 50. var isHasHealty:OCBool = true + 51. var isHasLover:OCBool = true + 52. + 53. isHasMoney != isHasHealty + 54. isHasHealty == isHasMoney + 55. isHasWife ^ isHasLover + 56. isHasWife = !isHasLover + 57. + 58. if (isHasMoney | isHasHealty) & isHasHealty{ + 59. println( "人生赢家,就像老码一样!") + 60. }else + 61. { + 62. println("人生最苦的事事,人死了钱没花了,人生最苦的事是,人活着,钱没了!") + 63. } + +好了,到这里就到这里了,窗外的雷声叫醒了老码,现在应该去吃饭了,以上老码给大家展示了如果制造一个自己的类型,记得老码的示例是在Xcode6 Beta4下测试的,至于Beta5的改变还没有涉及,小伙伴们要好生练习,以后各种自定类型都是基于这个思想。还有这个章节不是老码的原创,老码认真的阅读了苹果的官方博客,且自己的练习总结,如果小伙伴们费了吃奶的劲还是看不懂,请找度娘谷歌,还是看不懂请到老码官方微博:http://weibo.com/u/5241713117咆哮。 + + + +本文由翻译自Apple Swift Blog :https://developer.apple.com/swift/blog/?id=8 diff --git a/source/chapter4/chapter4.md b/source/chapter4/chapter4.md new file mode 100644 index 00000000..e69de29b