HackingWithSwift学习笔记_第1页
HackingWithSwift学习笔记_第2页
HackingWithSwift学习笔记_第3页
HackingWithSwift学习笔记_第4页
HackingWithSwift学习笔记_第5页
已阅读5页,还剩29页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Hacking With Swift 学习笔记目录前言3Introducing to Swift4ARRAYS,DICTIONARIES,LOOPS,SWITCH CASE5OPTIONALS6ENUMERATION7STRUCTS8CLASSES9PROPERTIES10ACCESS CONTROL11POLYMORPHISM AND TYPE CASTING12CLOSURES13本文档使用 看云 构建- 34 -前言原文:http:/frank1ee.github.io/blog/2015/09/13/hacking-with-swift-xue-xi-bi-ji/Hacking wit

2、h Swift 是由 Paul Hudson 发布的 免费 Swift 教程,其涵盖了30个项目,并且包含了 Swift 2.0。因为该教程是面向初学者,所以很多知识点都没有深入探讨,如果想要深入学习可以参考官方文档:The Swift Programming Language (Swift 2.1)Introducing to SwiftIntroducing to SwiftPlayground 是自 Xcode6 起苹果加入的实时浏览代码结果的一个功能。变量通过 var 声明,常量通过 let 声明。 Swift 可以推断变量的类型(type referen

3、ce),所以声明变量可以直接如下:var string = “My string”/也可以先声明类型(必须)或声明与赋值同时:var string:String = “My string”苹果官方建议在声明有小数部分的变量时都采用 Double,因其具有更高的精准度。Swift 中 bool 值是 true 和 false。“+” 号也可用于 string :var name1 = "Tim McGraw"var name2 =

4、0;"Romeo"var both = name1 + " and " + name2 /"Tim McGraw and Romeo"字符串的对比运算是”case-sensitive”,也就是区分大小写:var name = “TIM MCGRAW" var name2 =  "TiM m

5、CgRaW"name = name2  /result is false在 string 中插入变量:var name = “Tim McGraw”“Your name is (name)”/可以在括号中运算:var age = 25“His age is (age * 2)”ARRAYS,DICTIONARIES,LOOPS,SWITCH CASEARRAYS,DICTION

6、ARIES,LOOPS,SWITCH CASE通过类型注释(Type annotaions)可以申明数组内容的类型:var songs: String = "Shake it Off", "You Belong with Me", "Back to December", 3/以上会报错,因为数组内有非 String 类型的”3”在内。以下代码仅仅是声明了一个将要被分配包含Str

7、ing对象数组的变量:var array:String/没有真正创建数组对象var array: String = /这时才是创建了数组对象var array = String ()/效果同上,语法更为简洁。数组可以直接使用”+”运算符结合:var songs = "Shake it Off", "You Belong with Me", "Love

8、0;Story"var songs2 = "Today was a Fairytale", "White Horse", "Fifteen"var both = songs + songs2both += “Everything”/可以增加并赋值创建一个 Disctionary:var person =    

9、;   "first": "Taylor",      "middle": "Alison",      "last": "Swift",      "month": "December",

10、      "website": ""            Swift 中,条件表达式不需要括号:    if person = "hater"       action = "

11、hate"   else if person = "player"       action = "play"   else       action = "cruise"   在 Swift 2.0中,pri

12、ntln() 改为 print() Swift 的 for 循环语法:/ closed range operatorfor i in 1.10  println("(i) x 10 is (i * 10)")/*以上结果相当于:println("1 x 10 is (1 * 10)")println("2 x 

13、;10 is (2 * 10)")println("3 x 10 is (3 * 10)")println("4 x 10 is (4 * 10)")println("5 x 10 is (5 * 10)")println("6 x 10 is (6 

14、;* 10)")println("7 x 10 is (7 * 10)")println("8 x 10 is (8 * 10)")println("9 x 10 is (9 * 10)")println("10 x 10 is (10 * 10)")*/不需

15、要循环数时也可以用下划线代替:for _ in 1 . 5     str += " fake"half open range operator(半开区间运算符):“.<",例如 .<5 将会循环四次,count 将会是 1,2,3,4。”.<“ 可以方便于遍历数组(数组的 index 从0算起):for i in 0 .< count(people) 

16、    println("(peoplei) gonna (actionsi)")遍历数组的语法:.for song in songs     println("My favorite song is (song)")/通过 index 同时遍历俩数组:var people = "players", 

17、;"haters", "heart-breakers", "fakers"var actions = "play", "hate", "break", "fake"for i in 0 . 3     println("(peoplei) gonna 

18、;(actionsi)")       获取数组内的对象数量的方法在 Swift 1.2中是 count(array),在 Swift 2.0中是 array.count。 loop 中的 continue 语法 将会终止当前的迭代回到 loop 的开头继续迭代。switch/case 语法可以简化较多的 if/else if 语法,Swift 要求 switch 条件变量所有可能的情况都得涵盖( cases should exhustive),否则 Xcode 可

19、能无法构建应用,default 可以避免该问题。可以在 switch/case 中使用 “”(half open range operator) 将变量可能的范围作为一个 case:let studioAlbums = 5  switch studioAlbums       case 0.1:          println("You'

20、re just starting out")      case 2.3:          println("You're a rising star")      case 4.5:      &#

21、160;   println("You're world famous!")      default:          println("Have you done something new?")       Swift 2.

22、0 方法调用和1.2稍有不同,需要写明参数名,目的是提高代码可读性: func printAlbumRelease(name: String, year: Int)     println("(name) was released in (year)")printAlbumRelease("Fearless", year: 2008)printAlbumRelease("Speak

23、60;Now", year: 2010)printAlbumRelease("Red", year: 2012)“->"符号为方法声明返回值:func albumsIsTaylor(name: String) -> BoolOPTIONALSOPTIONALSApple 在 Swift 中为其加入了 Optional,Optional 是一种类型,可以有值,也可以等于 nil(也就是没有值)。在 oc 中,只有指向对象的指针可以为 nil,而在 swift 中基本

24、类型创建后没有初始值,而是为 nil,并且无法使用。开发中遇到的一些意想不到的问题,例如程序崩溃、影响UI,最常见的原因就是因为使用了为 nil 的值,Optional 这一特性确保了代码安全性。定义一个 Optional 的值只需在类型后添加一个问号“?”:var str: String? /输出nil/以上是一个名为 str 的 Optional String.Optional 类型无法直接使用,需要拆包(unwrap)后取出原类型的值后使用。在 Optional 类型后加上感叹号(!)进行显式拆包(Force unwr

25、apping optionals):var str: String? = "Hallo World"str  /nilstr!  /"Hallo World"print(str) /输出"Optional("Hallo World")"print(str!) /输出"Hallo World"通过 if let 语句可以判断 Optional 是否有值,如果有

26、,将其拆包赋值给一个本地变量:func getHaterStatus(weather: String) -> String?     if weather = "sunny"         return nil     else      &

27、#160;  return "Hate"        /该方法返回一个 Optional String 类型func takeHaterAction(status: String)     if status = "Hate"       

28、0; print("Hating")        /该方法需要传入一个 String 类型if let status = getHaterStatus("rainy")     takeHaterAction(status)/* if let 语句将调用了 getHaterStatus 方法后得到的

29、0;Optional 值拆包后赋值给本地变量 status,确保 takeHaterAction 方法传入的是一个有值的参数。 */Optional 还提供了隐式拆包(implicitly unwrapped optionals),隐式拆包的 Optional 在使用前无需拆包。要使用隐式拆包需要在变量声明时的数据类型后加上感叹号(!):var str: String! = "Hello World!"str /Hello World!使用隐式拆包需要小心

30、,要确保变量已被正确初始化。一般会在以下情况遇到 Implicitly unwrapped:当使用 Apple 的 API 时会经常碰到隐式拆包的返回值。当使用 UIKit 的用户界面元素时。总结一下 Optional:一个普通类型的变量必须有值,比如一个 String 变量需要拥有一个 string,哪怕是空的字符串("“)。一个 Optional 类型的变量可以有值也可以无值(也就是为nil),但在使用前必须将其拆包(Unwrap)。一个隐式拆包的 Optional 类型变量可以有值也可以无值,使用前不需要拆包,因此 Swift 也不会为你检查,需要格外小心。*Optional

31、Chaining: 在 Objective-C 中,对 nil 发送消息会得到 nil,但是在 Swift 中不允许这么做。当对一个 Optional 类型的对象发送消息时,通过 Optional Chaining 可以对其判断是否有值,如果是则发送消息,反之则什么也不做:func albumReleasedYear(year: Int) -> String?     switch year     case 2006: 

32、;return "Taylor Swift"    case 2008: return "Fearless"    case 2010: return "Speak Now"    case 2012: return "Red"    ca

33、se 2014: return "1989"    default: return nil    let album = albumReleasedYear(2006)?.uppercaseString /输出 Optional("TAYLOR SWFIT")/即问号(?)前有值才发送消息,这就是 Optional ChainingOptional

34、 Chaining 如同其名可以像链条一样连接,多长都可以,Swift 会从左至右检查直至发现 nil 即终止:let album = albumReleasedYear(2006)?.someOptionalValue?.someOtherOptionalValue?.whateverThe nil coalescing operator: Swift 的这个特性可以让你的代码更加简单和安全。例如:当 Value A 有值时则使用 Value A,如果 Value A 无值,则使用 Value B,这对 Opti

35、onal 十分有用:let album = albumReleasedYear(2006) ? "unknown"print("The album is (album)")/如果 albumReleasedYear(2006)返回的 Optional 无值,则使用非 Optional "unknown".ENUMERATIONENUMERATION枚举(Enum)可以将一系列相关的值定义为一个组类型,通过如

36、下语法创建 enum:enum WeatherType   case Sun, Cloud, Rain, Wind, Snow下面看看如何使用枚举类型:func getHaterStatus(weather: WeatherType) -> String?     if weather = WeatherType.Sun     &

37、#160;   return nil     else         return "Hate"    getHaterStatus(WeatherType.Cloud)也可以这么定义枚举:enum WeatherType     case Sun  

38、60; case Cloud    case Rain    case Wind    case Snow也可以这么使用枚举:func getHaterStatus(weather: WeatherType) -> String?     if weather = .Sun  

39、60;      return nil     else         return "Hate"      /Swift 通过 Type inference 知道你与 WeatherType 类型比较,所以无需写明枚举类型,但是这种写法

40、 Swift 将不会提供代码补足建议辅助getHaterStatus(.Cloud)枚举在 switch/case 中十分有用,因为 Swfit 知道你的枚举类型中都都有什么值,所以能确保你涵盖了所有的 case:func getHaterStatus(weather: WeatherType) -> String?     switch weather     case .Sun:  &#

41、160;     return nil    case .Cloud, .Wind:        return "dislike"    case .Rain:        return "hate"

42、60;       /这段代码不会成功编译,应该添加 case .Snow 或是 default case。对于 Enum,Swift 还有一个非常强大的特性:可以为组中的值再附加一个值,进一步细分:enum WeatherType     case Sun    case Cloud    case Rai

43、n    case Wind(speed: Int)    case Snow如此,使用 switch/case 时就有了额外的条件,当条件都满足时 case 才会匹配:func getHaterStatus(weather: WeatherType) -> String?     switch weather     case&#

44、160;.Sun:        return nil    case .Wind(let speed) where speed < 10: /meh        return "meh"    case .Cloud, 

45、.Wind:        return "dislike"    case .Rain, .Snow:        return "hate"    getHaterStatus(WeatherType.Wind(speed: 5)代码段第五行的 let 关键字的用

46、途是声明一个能引用的常量名保存传入的参数,通过 Where 关键字来声明条件。Swift 从上至下判断 switch/case 语句,所以请注意 case 的排序。STRUCTSSTRUCTSStructs(结构体) 是一种复杂数据类型,包含了多个值,通过 struct 关键字定义一个结构体:struct Person     var clothes: String    var shoes: StringSwift 让你非常简单地创建一个结构体变量,只需

47、要将初始值传入即可:let taylor = Person(clothes: "T-shirt", shoes: "sneakers")let other = Person(clothes: "short skirts, shoes: "high heels")通过结构体变量名以及属性名来访问属性的值:print(taylor.clothes)print(other.shoes)Swif

48、t 有一个名为"copy on write"的机制,当你将一个结构体变量赋给另一个变量时,会独立拷贝一份:struct Person     var clothes: String    var shoes: Stringlet taylor = Person(clothes: "T-shirts", shoes: "sneakers")

49、let other = Person(clothes: "short skirts", shoes: "high heels")var taylorCopy = taylortaylorCopy.shoes = "flip flops"taylor       /(clothes: "short s

50、kirts", shoes: "high heels")taylorCopy   /(clothes: "short skirts", shoes: "flip flops")CLASSESCLASSES通过 class 关键字定义一个类:class Person     var clothes: String  &#

51、160; var shoes: String但是上面有个问题,Swift 不允许创建未被正确初始化的变量。解决方法有三种:将这两个变量定义为 Optional。(这会致使代码中出现大量不必要的 Optional 类型)给变量附上一个初始值。(这行得通,但这有点浪费,除非这个初始值一定会被使用)自己写一个初始化方法。(最佳)通过创建一个 init() 方法来实现自定义初始化方法:class Person     var clothes: String   &

52、#160;var shoes: String   init(clothes: String, shoes: String)         self.clothes = clothes        self.shoes = shoes      &

53、#160; /init方法不需要添加 func 关键字    实例化一个类:var taylor = Person(name: "Taylor", age: 25)继承一个类:class Singer: Person 在 Swift 中,想要在继承类(子类)中覆盖父类的方法,需要使用 override 关键字:class Singer: Person override func sing() print(“Truck

54、s, girls, and liquor”) 通过 super 关键字调用父类方法:    init(name: String, age: Int, noiseLevel: Int)         self.noiseLevel = noiseLevel        super.init(name: na

55、me, age: age)    在 Swift 中,类和结构体有点相似,都可以拥有属性和方法,区别在于结构体是值拷贝,这意味着改变拷贝值不会改变原来的值,而类是指针拷贝,拷贝的变量会指向相同的实例,见下例:/ Value type examplestruct S  var data: Int = -1 var a = S()var b = a  

56、                      / a is copied to ba.data = 42                 &#

57、160;      / Changes a, not bprintln("(a.data), (b.data)")    / prints "42, -1"/ Reference type exampleclass C  var data: Int = -1 var&#

58、160;x = C()var y = x                        / x is copied to yx.data = 42        

59、;                / changes the instance referred to by x (and y)println("(x.data), (y.data)")    / prints "42, 42"P

60、ROPERTIESPROPERTIES结构体和类(统称为 types)可以拥有自己的变量和常量(统称为 properties)。types 也可拥有方法来处理 properties:struct Person    var clothes: String   var shoes: String   func describe()       print("I

61、 like wearing (clothes) with (shoes)")  let taylor = Person(clothes: "T-shirts", shoes: "sneakers")let other = Person(clothes: "short skirts", shoes: "high 

62、;heels")taylor.describe() /"I like wearing T-shirts with sneakers"other.describe() /"I like wearing short skirts with high heels"/调用方法时,不同的对象使用相应的值Property observersSwift 提供了两个观察者方法,willSet 和 didSet,分别会在属性

63、的值将要改变以及改变后触发(常用于用户界面的更新):struct Person     var clothes: String         willSet             updateUI("I'm changing from (cloth

64、es) to (newValue)")                didSet             updateUI("I just changed from (oldValue) to (clothe

65、s)")            func updateUI(msg: String)     print(msg)var taylor = Person(clothes: "T-shirts")taylor.clothes = "short skirts" /值改变,将会调用观察

66、者方法Computed propertiesComputed properties 其实就是自己重写属性的 get/set 方法:struct Person    var age: Int   var ageInDogYears: Int         get          

67、0;  return age * 7            var fan = Person(age: 25)print(fan.ageInDogYears) /输出:25 * 7Static properties and methods静态属性和方法属于 type(classstruct),而不属于类的实例,这可以更好的组织一个共享的储存数据。通过 sta

68、tic 关键字声明一个静态变量:struct TaylorFan     static var favoriteSong = "Shake it Off"   var name: String   var age: Intlet fan = TaylorFan(name: "James", 

69、;age: 25)print(TaylorFan.favoriteSong)/每个 TaylorFan 类型的对象都会有自己的名字和年龄,但他们都有共同喜欢的歌曲:"Shake it Off"因为静态属性和方法存在于 类 中,所以静态方法是无法访问非静态属性的。ACCESS CONTROLACCESS CONTROL在 Xcode beta4 中 Swift 增加了这个特性,Access control 让你明确在结构体、类中的数据该怎么面向外界,有以下三种关键字:Public:所有人都可以读写属性。Internal:这是默

70、认访问级别,模块中的 swift 代码都可以访问。Private:只有当前Swift源文件可以访问。大多数时候你不必明确访问级别,但有些时候你会需要将一个属性设为 private ,使其无法被其他人直接访问。 这样声明一个 private 的属性:class TaylorFan     private var name: String!注意:Playground 不受 Access control 的限制,因为它可以无碍地访问文件因此它可以读写任何数据。POLYMORPHISM AND TYPE CAST

71、INGPOLYMORPHISM AND TYPE CASTINGPolymorphism 译为多态,指的是在类的继承中,子类会继承父类的属性、方法,多态即指子类可以拥有父类或自身定义的两种行为,你可以为其选择:class Album    var name: String   init(name: String)          = name &#

72、160;  class StudioAlbum: Album    var studio: String   init(name: String, studio: String)         self.studio = studio        

73、;super.init(name: name)    class LiveAlbum: Album    var location: String   init(name: String, location: String)         self.location = location 

74、;       super.init(name: name)    /子类调用父类方法,实现父类的行为    当子类想要实现自己的行为时,可以通过  override 关键字 重写 父类方法,如此将会实现子类自己定义的方法行为:class LiveAlbum: Album     var location: String 

75、60; init(name: String, location: String)         self.location = location        super.init(name: name)       override func getPerforma

76、nce() -> String         return "The live album (name) sold lots"    总而言之,一个对象可以同时实现自己类的行为和其父类的行为,这称为多态。Converting types with type casting这种情况时有发生:你有一个明确声明的对象,但你知道它其实是另一种类型(比如上面的继承类St

77、udioAlbum 和 LiveAlbum 被当做 Album 保存在数组中,因为它们继承于 Album 所以是允许的),当需要调用方法时,Swift 可能不知道它的真实类型而无法编译,解决办法是 type casting,即类型转换,可以将一个对象的类型转为另一种类型:for album in allAlbums     print(album.getPerformance() /根据上面代码块的内容 allAlbums  数组拥有三个类型为  Album  的对象,但是其

78、中两个我们知道是 StudioAlbum  和  LiveAlbum ,但是 Swift 却不知道,如果你想执行 print(album.studio)  则无法编译,因为只有  StudioAlbum 拥有那个属性。Type casting 有三种形式,但常见的只有两种: as?  和  as! ,分别是可选向下转型以及强制向下转型,前者会返回一个转型后的可选值(optional value),若转型失败会返回nil;当你确定可以转型成功时使用后者,如果转型失败可能导致应用崩溃: P.S.转型并不是指真的改变实例或它的值,

79、而只是告诉 Swift 把这个对象看做某个类的实例。for album in allAlbums     let studioAlbum = album as? StudioAlbumstudioAlbum 变量将会拥有一个StudioAlbum?类型数据或是nil,这经常与 if let 配合使用来自动解包 optional 值:for album in allAlbums    print(album.getPerformance()   if let studioAlbum 

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论