HackingWithSwift學(xué)習(xí)筆記_第1頁
HackingWithSwift學(xué)習(xí)筆記_第2頁
HackingWithSwift學(xué)習(xí)筆記_第3頁
HackingWithSwift學(xué)習(xí)筆記_第4頁
HackingWithSwift學(xué)習(xí)筆記_第5頁
已閱讀5頁,還剩29頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、Hacking With Swift 學(xué)習(xí)筆記目錄前言3Introducing to Swift4ARRAYS,DICTIONARIES,LOOPS,SWITCH CASE5OPTIONALS6ENUMERATION7STRUCTS8CLASSES9PROPERTIES10ACCESS CONTROL11POLYMORPHISM AND TYPE CASTING12CLOSURES13本文檔使用 看云 構(gòu)建- 34 -前言原文:http:/frank1ee.github.io/blog/2015/09/13/hacking-with-swift-xue-xi-bi-ji/Hacking wit

2、h Swift 是由 Paul Hudson 發(fā)布的 免費 Swift 教程,其涵蓋了30個項目,并且包含了 Swift 2.0。因為該教程是面向初學(xué)者,所以很多知識點都沒有深入探討,如果想要深入學(xué)習(xí)可以參考官方文檔:The Swift Programming Language (Swift 2.1)Introducing to SwiftIntroducing to SwiftPlayground 是自 Xcode6 起蘋果加入的實時瀏覽代碼結(jié)果的一個功能。變量通過 var 聲明,常量通過 let 聲明。 Swift 可以推斷變量的類型(type referen

3、ce),所以聲明變量可以直接如下:var string = “My string”/也可以先聲明類型(必須)或聲明與賦值同時:var string:String = “My string”蘋果官方建議在聲明有小數(shù)部分的變量時都采用 Double,因其具有更高的精準(zhǔn)度。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”,也就是區(qū)分大小寫: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)可以申明數(shù)組內(nèi)容的類型:var songs: String = "Shake it Off", "You Belong with Me", "Back to December", 3/以上會報錯,因為數(shù)組內(nèi)有非 String 類型的”3”在內(nèi)。以下代碼僅僅是聲明了一個將要被分配包含Str

7、ing對象數(shù)組的變量:var array:String/沒有真正創(chuàng)建數(shù)組對象var array: String = /這時才是創(chuàng)建了數(shù)組對象var array = String ()/效果同上,語法更為簡潔。數(shù)組可以直接使用”+”運算符結(jié)合: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”/可以增加并賦值創(chuàng)建一個 Disctionary:var person =    

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

10、      "website": ""            Swift 中,條件表達(dá)式不需要括號:    if person = "hater"       action = "

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

12、ntln() 改為 print() Swift 的 for 循環(huán)語法:/ closed range operatorfor i in 1.10  println("(i) x 10 is (i * 10)")/*以上結(jié)果相當(dāng)于: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、要循環(huán)數(shù)時也可以用下劃線代替:for _ in 1 . 5     str += " fake"half open range operator(半開區(qū)間運算符):“.<",例如 .<5 將會循環(huán)四次,count 將會是 1,2,3,4?!?<“ 可以方便于遍歷數(shù)組(數(shù)組的 index 從0算起):for i in 0 .< count(people) 

16、    println("(peoplei) gonna (actionsi)")遍歷數(shù)組的語法:.for song in songs     println("My favorite song is (song)")/通過 index 同時遍歷倆數(shù)組:var people = "players", 

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

18、;(actionsi)")       獲取數(shù)組內(nèi)的對象數(shù)量的方法在 Swift 1.2中是 count(array),在 Swift 2.0中是 array.count。 loop 中的 continue 語法 將會終止當(dāng)前的迭代回到 loop 的開頭繼續(xù)迭代。switch/case 語法可以簡化較多的 if/else if 語法,Swift 要求 switch 條件變量所有可能的情況都得涵蓋( cases should exhustive),否則 Xcode 可

19、能無法構(gòu)建應(yīng)用,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 方法調(diào)用和1.2稍有不同,需要寫明參數(shù)名,目的是提高代碼可讀性: 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 中,只有指向?qū)ο蟮闹羔樋梢詾?nil,而在 swift 中基本

24、類型創(chuàng)建后沒有初始值,而是為 nil,并且無法使用。開發(fā)中遇到的一些意想不到的問題,例如程序崩潰、影響UI,最常見的原因就是因為使用了為 nil 的值,Optional 這一特性確保了代碼安全性。定義一個 Optional 的值只需在類型后添加一個問號“?”:var str: String? /輸出nil/以上是一個名為 str 的 Optional String.Optional 類型無法直接使用,需要拆包(unwrap)后取出原類型的值后使用。在 Optional 類型后加上感嘆號(!)進(jìn)行顯式拆包(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 語句將調(diào)用了 getHaterStatus 方法后得到的

29、0;Optional 值拆包后賦值給本地變量 status,確保 takeHaterAction 方法傳入的是一個有值的參數(shù)。 */Optional 還提供了隱式拆包(implicitly unwrapped optionals),隱式拆包的 Optional 在使用前無需拆包。要使用隱式拆包需要在變量聲明時的數(shù)據(jù)類型后加上感嘆號(!):var str: String! = "Hello World!"str /Hello World!使用隱式拆包需要小心

30、,要確保變量已被正確初始化。一般會在以下情況遇到 Implicitly unwrapped:當(dāng)使用 Apple 的 API 時會經(jīng)常碰到隱式拆包的返回值。當(dāng)使用 UIKit 的用戶界面元素時??偨Y(jié)一下 Optional:一個普通類型的變量必須有值,比如一個 String 變量需要擁有一個 string,哪怕是空的字符串("“)。一個 Optional 類型的變量可以有值也可以無值(也就是為nil),但在使用前必須將其拆包(Unwrap)。一個隱式拆包的 Optional 類型變量可以有值也可以無值,使用前不需要拆包,因此 Swift 也不會為你檢查,需要格外小心。*Optional

31、Chaining: 在 Objective-C 中,對 nil 發(fā)送消息會得到 nil,但是在 Swift 中不允許這么做。當(dāng)對一個 Optional 類型的對象發(fā)送消息時,通過 Optional Chaining 可以對其判斷是否有值,如果是則發(fā)送消息,反之則什么也不做: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")/即問號(?)前有值才發(fā)送消息,這就是 Optional ChainingOptional

34、 Chaining 如同其名可以像鏈條一樣連接,多長都可以,Swift 會從左至右檢查直至發(fā)現(xiàn) nil 即終止:let album = albumReleasedYear(2006)?.someOptionalValue?.someOtherOptionalValue?.whateverThe nil coalescing operator: Swift 的這個特性可以讓你的代碼更加簡單和安全。例如:當(dāng) 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)可以將一系列相關(guān)的值定義為一個組類型,通過如

36、下語法創(chuàng)建 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 將不會提供代碼補(bǔ)足建議輔助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;       /這段代碼不會成功編譯,應(yīng)該添加 case .Snow 或是 default case。對于 Enum,Swift 還有一個非常強(qiáng)大的特性:可以為組中的值再附加一個值,進(jìn)一步細(xì)分:enum WeatherType     case Sun    case Cloud    case Rai

43、n    case Wind(speed: Int)    case Snow如此,使用 switch/case 時就有了額外的條件,當(dāng)條件都滿足時 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 關(guān)鍵字的用

46、途是聲明一個能引用的常量名保存?zhèn)魅氲膮?shù),通過 Where 關(guān)鍵字來聲明條件。Swift 從上至下判斷 switch/case 語句,所以請注意 case 的排序。STRUCTSSTRUCTSStructs(結(jié)構(gòu)體) 是一種復(fù)雜數(shù)據(jù)類型,包含了多個值,通過 struct 關(guān)鍵字定義一個結(jié)構(gòu)體:struct Person     var clothes: String    var shoes: StringSwift 讓你非常簡單地創(chuàng)建一個結(jié)構(gòu)體變量,只需

47、要將初始值傳入即可:let taylor = Person(clothes: "T-shirt", shoes: "sneakers")let other = Person(clothes: "short skirts, shoes: "high heels")通過結(jié)構(gòu)體變量名以及屬性名來訪問屬性的值:print(taylor.clothes)print(other.shoes)Swif

48、t 有一個名為"copy on write"的機(jī)制,當(dāng)你將一個結(jié)構(gòu)體變量賦給另一個變量時,會獨立拷貝一份: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 關(guān)鍵字定義一個類:class Person     var clothes: String  &#

51、160; var shoes: String但是上面有個問題,Swift 不允許創(chuàng)建未被正確初始化的變量。解決方法有三種:將這兩個變量定義為 Optional。(這會致使代碼中出現(xiàn)大量不必要的 Optional 類型)給變量附上一個初始值。(這行得通,但這有點浪費,除非這個初始值一定會被使用)自己寫一個初始化方法。(最佳)通過創(chuàng)建一個 init() 方法來實現(xiàn)自定義初始化方法: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 關(guān)鍵字    實例化一個類:var taylor = Person(name: "Taylor", age: 25)繼承一個類:class Singer: Person 在 Swift 中,想要在繼承類(子類)中覆蓋父類的方法,需要使用 override 關(guān)鍵字:class Singer: Person override func sing() print(“Truck

54、s, girls, and liquor”) 通過 super 關(guān)鍵字調(diào)用父類方法:    init(name: String, age: Int, noiseLevel: Int)         self.noiseLevel = noiseLevel        super.init(name: na

55、me, age: age)    在 Swift 中,類和結(jié)構(gòu)體有點相似,都可以擁有屬性和方法,區(qū)別在于結(jié)構(gòu)體是值拷貝,這意味著改變拷貝值不會改變原來的值,而類是指針拷貝,拷貝的變量會指向相同的實例,見下例:/ 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結(jié)構(gòu)體和類(統(tǒng)稱為 types)可以擁有自己的變量和常量(統(tǒng)稱為 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"/調(diào)用方法時,不同的對象使用相應(yīng)的值Property observersSwift 提供了兩個觀察者方法,willSet 和 didSet,分別會在屬性

63、的值將要改變以及改變后觸發(fā)(常用于用戶界面的更新):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" /值改變,將會調(diào)用觀察

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靜態(tài)屬性和方法屬于 type(classstruct),而不屬于類的實例,這可以更好的組織一個共享的儲存數(shù)據(jù)。通過 sta

68、tic 關(guān)鍵字聲明一個靜態(tài)變量: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"因為靜態(tài)屬性和方法存在于 類 中,所以靜態(tài)方法是無法訪問非靜態(tài)屬性的。ACCESS CONTROLACCESS CONTROL在 Xcode beta4 中 Swift 增加了這個特性,Access control 讓你明確在結(jié)構(gòu)體、類中的數(shù)據(jù)該怎么面向外界,有以下三種關(guān)鍵字:Public:所有人都可以讀寫屬性。Internal:這是默

70、認(rèn)訪問級別,模塊中的 swift 代碼都可以訪問。Private:只有當(dāng)前Swift源文件可以訪問。大多數(shù)時候你不必明確訪問級別,但有些時候你會需要將一個屬性設(shè)為 private ,使其無法被其他人直接訪問。 這樣聲明一個 private 的屬性:class TaylorFan     private var name: String!注意:Playground 不受 Access control 的限制,因為它可以無礙地訪問文件因此它可以讀寫任何數(shù)據(jù)。POLYMORPHISM AND TYPE CAST

71、INGPOLYMORPHISM AND TYPE CASTINGPolymorphism 譯為多態(tài),指的是在類的繼承中,子類會繼承父類的屬性、方法,多態(tài)即指子類可以擁有父類或自身定義的兩種行為,你可以為其選擇: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)    /子類調(diào)用父類方法,實現(xiàn)父類的行為    當(dāng)子類想要實現(xiàn)自己的行為時,可以通過  override 關(guān)鍵字 重寫 父類方法,如此將會實現(xiàn)子類自己定義的方法行為: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"    總而言之,一個對象可以同時實現(xiàn)自己類的行為和其父類的行為,這稱為多態(tài)。Converting types with type casting這種情況時有發(fā)生:你有一個明確聲明的對象,但你知道它其實是另一種類型(比如上面的繼承類St

77、udioAlbum 和 LiveAlbum 被當(dāng)做 Album 保存在數(shù)組中,因為它們繼承于 Album 所以是允許的),當(dāng)需要調(diào)用方法時,Swift 可能不知道它的真實類型而無法編譯,解決辦法是 type casting,即類型轉(zhuǎn)換,可以將一個對象的類型轉(zhuǎn)為另一種類型:for album in allAlbums     print(album.getPerformance() /根據(jù)上面代碼塊的內(nèi)容 allAlbums  數(shù)組擁有三個類型為  Album  的對象,但是其

78、中兩個我們知道是 StudioAlbum  和  LiveAlbum ,但是 Swift 卻不知道,如果你想執(zhí)行 print(album.studio)  則無法編譯,因為只有  StudioAlbum 擁有那個屬性。Type casting 有三種形式,但常見的只有兩種: as?  和  as! ,分別是可選向下轉(zhuǎn)型以及強(qiáng)制向下轉(zhuǎn)型,前者會返回一個轉(zhuǎn)型后的可選值(optional value),若轉(zhuǎn)型失敗會返回nil;當(dāng)你確定可以轉(zhuǎn)型成功時使用后者,如果轉(zhuǎn)型失敗可能導(dǎo)致應(yīng)用崩潰: P.S.轉(zhuǎn)型并不是指真的改變實例或它的值,

79、而只是告訴 Swift 把這個對象看做某個類的實例。for album in allAlbums     let studioAlbum = album as? StudioAlbumstudioAlbum 變量將會擁有一個StudioAlbum?類型數(shù)據(jù)或是nil,這經(jīng)常與 if let 配合使用來自動解包 optional 值:for album in allAlbums    print(album.getPerformance()   if let studioAlbum 

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論