前言:swift語法基礎篇(二)來了,想學習swift的朋友可以拿去參考哦,有興趣可以相互探討,共同學習哦. 一.可選類型(重點內容) 1.什麼是可選類型? 1.1在OC開發中,如果一個變數暫停不使用,可以賦值為0(基本屬性類型)或者賦值為空(對象類型) 1.2在swift開發中,nil也是一個特殊 ...
前言:swift語法基礎篇(二)來了,想學習swift的朋友可以拿去參考哦,有興趣可以相互探討,共同學習哦.
一.可選類型(重點內容) 1.什麼是可選類型? 1.1在OC開發中,如果一個變數暫停不使用,可以賦值為0(基本屬性類型)或者賦值為空(對象類型) 1.2在swift開發中,nil也是一個特殊的類型.因為和真實的類型不匹配是不能賦值的(swift是強類型語言) 1.3但是開發中賦值nil,在所難免.因此推出了可選類型 目的:讓代碼更加嚴謹 2.可選類型的取值 可選類型要麼是:空值 , 要麼是:有值 只有為可選類型,才能賦值為nil 3.定義可選類型 3.1 普通寫法
var name : Optional<String> = nil3.2 簡單寫法(語法糖)
var name : String? = nil4.給可選類型賦值 4.1 普通賦值
name = Optional("why")4.2 直接賦值
name = "why" // 系統會對字元串進行包裝Optional, 再進行賦值5.強制解包(取出可選類型中具體的值) 5.1 為什麼要強制解包 可選類型的值的格式為: Optional("why") 我們要想使用其真實值,必須要解包 5.2 怎麼解包? 在可選類型的標識符後面加!
print(name!)註意:解包前,要先判斷可選類型是否為nil , 如果為nil,強制解包會報錯 6.可選綁定
1 if let name = name { 2 print(name) 3 print(name) 4 }6.1 系統先判斷可選類型是否為nil,如果為nil,就跳過{}中的內容 6.2 如果有值,會先對name進行強制解包,然後把解包結果賦值給name
7.可選類型的應用場景 可選類型能讓代碼變得更加嚴謹 類型轉換後的數據類型一般都為可選類型,因為轉換不成功就為nil , 只有可選類型能接收nil 7.1字元串類型轉Int類型 可以看到,類型轉換後的類型為可選類型 使用轉換後的結果的時候,一定要先判斷是否為nil, 如果為nil, 使用會報錯 7.2 根據string創建一個NSURL
1 let urlString = "www.baidu.com" 2 3 let url : NSURL? = NSURL(string: urlString) 4 if let url = url { 5 let request = NSURLRequest(URL: url) 6 }if let url = url 內部做了以下判斷: 1.判斷url是否為nil,為nil 就跳過{}中的內容 2.不為nil,就對url進行強制解包 3.將解包後的結果賦值給前面的url 7.3 根據一個plist文件創建一個數組
1 let path = NSBundle.mainBundle().pathForResource("123.plist", ofType: nil) 2 3 if let path = path { 4 NSArray(contentsOfFile:path) 5 }二.類型轉化 1.is的使用:判斷是否是某種類型
1 //1.is的使用 2 let infoArray = ["why" , 18 , 1.98] 3 let item = infoArray[1] 4 5 //item.isKindOfClass(UIButton.self) 6 7 //string是結構體,不能用isKindOfClass 8 if item is String { 9 print("是字元串") 10 }else { 11 print("不是字元串") 12 }
2.as的使用 2.1 as直接使用: swift類型和oc類型的轉化
1 let urlString = "www.baidu.com" 2 (urlString as NSString).substringToIndex(3)2.2 as? 的使用: 將NSObject轉成某一確定類型的可選類型
1 let item1 = infoArray[0] 2 let name = item1 as? String 3 if let name = name { 4 print(name.characters.count) 5 } 6 簡寫: 7 if let name = infoArray[0] as? String { 8 print(name.characters.count) 9 }2.3 as! 的使用: 將NSObject轉成確定的類型,但如果轉化不成功,則程式會崩潰
1 let count = (infoArray[0] as! String).characters.count三.函數 1.函數的介紹 1.1 函數相當於OC中的方法 1.2 函數的格式如下 func 函數名(參數列表) -> 返回值類型 { 代碼塊 return 返回值
}
1.3 func是關鍵字,多個參數列表之間可以用逗號(,)分隔,也可以沒有參數
1.4 使用箭頭“->”指向返回值類型
1.5 如果函數沒有返回值,返回值為Void.並且“-> 返回值類型”部分可以省略
2.常見的函數類型
3.內部參數和外部參數
3.1 什麼是內部參數
3.11 在函數內部就可以看到的參數(標識符)就是內部參數
3.12 預設所有的參數都是內部參數
3.2 什麼是外部參數
3.21 在函數外部就可以看到的參數(標識符)就是外部參數
3.22 預設從第二個參數開始都是外部參數
3.23 如果想讓第一個參數成為外部參數,可以設置標簽:在變數名前加標簽即可
3.24 如果不想要外部參數,可以在參數名稱前加_ (_ 和參數名稱中間要加一個 空格)
3.25 也可以給外部參數設置標簽 ,相當於給外部參數起別名
4.預設參數
4.1 什麼是預設參數?
如果一個函數需要參數,而我們調用的時候又不想傳參,那麼在設計函數的時候,可以給函數一個預設的參數
如果調用函數,不傳參數,就按照預設的參數對函數進行處理
5.可變參數 5.1 swift中函數的參數個數可以變化,它可以接收不確定數量的輸入類型參數 5.2 它們必須具有相同的類型 5.3 我們可以通過在參數類型名後面加入(...)的方式來指示這是可變參數 作用:方便需求變化時,更改代碼,當參數個數需求變更或很多時,可以輕鬆些代碼
6.指針參數 6.1 預設情況下,函數的參數是值傳遞.如果想改變外面的變數,則需要傳遞變數的地址 6.2 必須是變數,因為需要在內部改變其值 6.3 Swift提供的inout關鍵字就可以實現
7.函數的嵌套 swift中函數是可以嵌套的,即函數中包含函數,但是不推薦該寫法 OC中方法不可以嵌套
1 // 函數的嵌套 2 let value = 55 3 func test() { 4 func demo() { 5 print("demo \(value)") 6 } 7 print("test") 8 demo() 9 } 10 demo() // 錯誤 必須在對應的作用域內調用 11 test() // 執行函數會先列印'test',再列印'demo'8.函數的類型 8.1什麼是函數的類型? 每個函數都有自己的類型, 函數的類型由 函數的參數類型和返回值類型組成
1 // 定義兩個函數 2 func addTwoInts(a : Int, b : Int) -> Int { 3 return a + b 4 } 5 6 func multiplyTwoInt(a : Int, b : Int) -> Int { 7 return a * b 8 } 9這兩個函數的類型是 (Int, Int) -> Int 8.2抽取兩個函數的類型,並且使用
1 // 定義函數的類型 2 var mathFunction : (Int, Int) -> Int = addTwoInts 3 4 // 使用函數的名稱 5 mathFunction(10, 20) 6 7 // 給函數的標識符賦值其他值 8 mathFunction = multiplyTwoInt 9 10 // 使用函數的名稱 11 mathFunction(10, 20)8.3 函數作為方法的參數
1 // 3.將函數的類型作為方法的參數 2 func printResult(a : Int, b : Int, calculateMethod : (Int, Int) -> Int) { 3 print(calculateMethod(a, b)) 4 } 5 6 printResult(10, b: 20, calculateMethod: addTwoInts) 7 printResult(10, b: 20, calculateMethod: multiplyTwoInt)8.4函數作為方法的返回值
1 // 1.定義兩個函數 2 func stepForward(num : Int) -> Int { 3 return num + 1 4 } 5 6 func stepBackward(num : Int) -> Int { 7 return num - 1 8 } 9 10 // 2.定義一個變數,希望該變數經過計算得到0 11 var num = -4 12 13 // 3.定義獲取哪一個函數 14 func getOprationMethod(num : Int) -> (Int) -> Int { 15 return num <= 0 ? stepForward : stepBackward 16 } 17 18 // 4.for迴圈進行操作 19 while num != 0 { 20 let oprationMethod = getOprationMethod(num) 21 num = oprationMethod(num) 22 print(num) 23 }四.枚舉類型 1.什麼是枚舉? 1.1 枚舉是一種數據類型,枚舉是一組具有共同特性的數據的集合 1.2 枚舉可以讓我們更安全的使用數據 1.3 oc中只能對枚舉成員賦值為整型 1.4 swift中的枚舉更加靈活,可以給每一枚舉成員賦值,這些值可以為字元,字元串,整型,浮點型等 2.枚舉類型的定義 2.1 使用enum關鍵詞,把枚舉定義在一個大括弧內
1 enum <#name#> { 2 case <#case#> 3 }2.2 case關鍵詞表明新的一行成員值將被定義 2.3 不像 C 和 Objective-C 一樣,Swift 的枚舉成員在被創建時不會被賦予一個預設的整數值 (0.1.2.3...) 2.4 定義方式二: 多個成員值可以寫在同一行
1 enum Planet { 2 case Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune 3 }3.枚舉類型的使用
1 enum Direction : Int{ 2 case East = 1 , West , North , Sourth 3 } 4 //完整寫法 5 let d : Direction = Direction.North 6 //簡單寫法:根據上下文能推導出確定的類型 7 var d1 = Direction.East 8 d1 = .West 9 10 //枚舉類型的使用 11 let btn = UIButton(type: .Custom)4.給枚舉類型賦值 4.1 枚舉類型賦值可以是字元串/字元/整型/浮點型 4.2 註意: 如果給枚舉類型賦值, 則必須在枚舉類型後面說明賦值的類型 4.3 給枚舉類型賦的值的類型,必須跟說明的類型一致,否則會報錯
1 let btn = UIButton(type: .Custom) 2 3 enum Direction : String{ 4 case East = "1" 5 case West = "3" 6 case North = "6" 7 case Sourth = "9" 8 } 9 var b : Direction = .West 10 11 let a = Direction(rawValue: “6”)註意: 通過rawValue:方式取出來的值的類型 為 對應類型的 可選類型 因為通過這種方法不一定能取出來值,可能為nil 所以為可選類型 比較嚴謹 4.4給枚舉類型賦值方式二
1 enum Direction2 : Int{ 2 case East = 1 , West , North , Sourth 3 //只要給第一個成員賦值,會自動按照遞增的方式給後面的成員賦值 4 //相當於 West = 2, North = 3, Sourth = 4 5 //註意:這種賦值方法只對整型有效,賦值其它類型無效五.結構體 1.什麼是結構體? 1.1結構體(struct)是由一系列具有相同類型或不同類型的數據構成的數據集合 1.2結構體(struct)指的是一種數據結構 1.3結構體是值類型,在方法中傳遞時是值傳遞 2.結構的定義格式
struct 結構體名稱 {
// 屬性和方法
}
3.在swift中對結構體進行了很大的增強
3.1 擴充構造函數
3.11 預設情況下,創建Location 只能使用Location (x: Double , y : Double) 方法創建
3.12 但為了讓結構體的使用更加靈活, swift中,可以對其構造方法就行擴充
3.13 註意: 結構體中值必須為可變的var ,否則沒有意義
3.2 為結構體擴充方法 六.類 1.類的介紹和定義 1.1 Swift也是一門面向對象開發的語言,面向對象的基礎是類,類產生了對象 1.2 在swift中如何定義類? class是Swift中的關鍵字,用於定義類 1.3 定義的類,可以沒有父類.那麼該類是rootClass 1.4 通常情況下,定義類時.繼承自NSObject
1 class 類名 : SuperClass { 2 // 定義屬性和方法 3 } 4 class Person { 5 var name : String = "" 6 var age : Int = 0 7 } 8 let p = Person() 9 p.name = "lkj" 10 p.age = 182.類的屬性定義 2.1類的屬性介紹:Swift中類的屬性有多種 存儲屬性:存儲實例的常量和變數 計算屬性:通過某種方式計算出來的屬性 類屬性:與整個類自身相關的屬性
3.監聽屬性的改變 3.1 在OC中我們可以重寫set方法來監聽屬性的改變 (kvc監聽系統屬性的改變) 3.2 Swift中可以通過屬性觀察者來監聽和響應屬性值的變化 3.3 通常是監聽存儲屬性和類屬性的改變.(對於計算屬性不需要定義屬性觀察者,因為可以在計算屬性的set方法中直接觀察) 3.4 怎麼監聽? 通過willSet 和didSet兩個方法來監聽 , 統稱為屬性監聽器
4.類的構造函數 4.1 構造函數類似於OC中的初始化方法: init方法 4.2 創建一個類,系統會預設提供一個構造函數 4.3 自定義構造函數 , 一般用來初始化時給屬性賦值 註意:如果自定義構造函數,會覆蓋系統預設提供的構造函數 , 如果想保留,需要重寫
1 class Person { 2 var name : String 3 var age : Int 4 // 自定義構造函數,會覆蓋init()函數 5 init(name : String, age : Int) { 6 // 如果在一個方法中, 屬性名稱產生了歧義(重名), self.不可以省略 7 self.name = name 8 self.age = age 9 } 10 } 11 // 創建一個Person對象 12 let p = Person(name: "why", age: 18) 13 14 15 class Person: NSObject { 16 var name : String 17 var age : Int 18 // 重寫了NSObject(父類)的構造方法 在init前面加上override 19 override init() { 20 name = "" 21 age = 0 22 } 23 } 24 // 創建一個Person對象 25 let p = Person()5.字典轉模型 5.1 使用kvc的條件? 5.11 必須繼承自NSObject 5.12 在構造函數中使用,必須先調用super.init() 5.2 利用kvc字典轉模型非常方便 5.3 使用kvc註意點 5.31 屬性需要有預設的值 5.32 基本數據類型預設值一般設置為0 5.33 對象或結構體類型定義為可選類型(可選類型沒有賦值前為nil)
1 class Person: NSObject { 2 // 結構體或者類的類型,必須是可選類型.因為不能保證一定會賦值 3 var name : String? 4 // 基本數據類型不能是可選類型,否則KVC無法轉化 5 var age : Int = 0 6 // 自定義構造函數,會覆蓋init()函數 7 init(dict : [String : NSObject]) { 8 // 必須先初始化對象 9 super.init() 10 // 調用對象的KVC方法字典轉模型 11 setValuesForKeysWithDictionary(dict) 12 } 13 //如果字典中某些鍵值對,在類中找不到對應的屬性,就會報錯 14 //不想讓它報錯,可以重寫setValue forUndefinedKey key: 15 override func setValue(value: AnyObject?, forUndefinedKey key: String) { 16 } 17 } 18 // 創建一個Person對象 19 let dict = ["name" : "why", "age" : 18] 20 let p = Person(dict: dict)6.析構函數 6.1 swift會自動釋放不需要的實例以釋放資源 6.11 swift 通過ARC 處理實例的記憶體管理 6.12 當引用計數為0時,系統會自動調用析構函數(不可以手動調用) 6.13 通常在析構函數中釋放一些資源(如:移除通知等操作) 6.2 析構函數的寫法
1 deinit { 2 // 執行析構過程 3 }6.21 示例練習
1 class Person { 2 var name : String 3 var age : Int 4 5 init(name : String, age : Int) { 6 self.name = name 7 self.age = age 8 } 9 10 deinit { 11 print("Person-deinit") 12 } 13 } 14 15 var p : Person? = Person(name: "why", age: 18) 16 p = nil