1 person.dog!.toy!.price = 50 太危險 強制解包,如果沒值,直接程序崩潰 2 3 if let dog = person.dog { 4 if let toy = dog.toy { 5 toy.price = 50 6 } 這樣解包雖然安全,但是太麻煩 7 }蘋果在swift中推薦使用這種方式來給可選鏈賦值
1 person.dog?.toy?.price = 50 2 //當person.dog 為nil的時候,後面的操作就不再執行4.2 從可選鏈取值: 從可選鏈中取出的值得類型一定是可選類型 (有可能取不到)
let price = person.dog?.toy?.price4.3 可選鏈調用方法:系統會自動判斷可選類型是否有值
person.dog?.toy?.flying()三.協議 1.如何定義協議 1.1 swift中協議的方式和類,結構體,枚舉相似
protocol SomeProtocol { // 協議方法 }1.2 例如:定義一個運動協議
1 protocol SportProtocol { 2 func playBasketball() 3 func playFootball() 4 }2.聲明一個類,並且遵守協議 2.1 聲明一個基類(不繼承其它類),並遵守協議
1 class SomeClass:FirstProtocol,AnotherProtocol { 2 // 類的內容 3 // 實現協議中的方法 4 } 5 6 例如: 7 class Person : SportProtocol { 8 var name : String = "" 9 10 func playBasketball() { 11 print("打籃球") 12 } 13 14 func playFootball() { 15 print("踢足球") 16 } 17 }2.2 類繼承自其他類,並遵守協議
1 class SomeClass:SomeSuperClass, FirstProtocol,AnotherProtocol { 2 // 類的內容 3 // 實現協議中的方法 4 }3.OC swift不支持多繼承, 但是可以通過協議,間接實現多繼承 4.協議的繼承關系 4.1 swift中的及協議和OC(NSObject)中的不同 是:NSObjectProtocol
1 protocol CrazySportProtocol : NSObjectProtocol { 2 func jumping() 3 }4.2 一個協議,可以遵守另一個協議
1 protocol SportProtocol : CrazySportProtocol { 2 func playBasketball() 3 }當一個類遵守了這個協議(SportProtocol) 相當於也遵守了CrazySportProtocol 協議, 所以必須實現這兩個協議中的方法 5.協議的可選性 5.1 OC中協議可以定義為可選和必選,默認是必選的 5.2 默認情況下,swift中的協議都是必須實現的 ,否則編譯器會報錯 5.3 在swift中如何讓協議成為可選的(不用必須實現) 要在協議前加 @objc ,可以保留OC某些特性,在方法前加optional 該方法就是可選的了 在實現協議方法時,在方法前面也要加@objc
1 @objc protocol SportProtocol { 2 func playBasketball() 3 func playFootball() 4 //加optional該方法就成為可選的了 5 optional func jumping() 6 } 7 8 class Person: SportProtocol { 9 @objc func playBasketball() { 在方法前也要加上關鍵字@objc,不管是可選還是必選 10 } 11 @objc func playFootball() { 12 } 13 @objc func jumping() { 14 } 15 }
6.協議在代理模式中的使用 6.1 一般來說協議都用weak來修飾(弱引用) 6.2 weak只能用來修飾類 6.3 在swift中協議既可以被類遵守,也可以被結構體,枚舉遵守 6.4 如何讓協議只能被類准守 在協議名稱後面加上 :class 即可 四.閉包 1.什麼是閉包? 閉包和OC中的block非常相似,一般都用來函數的回調 2.block的回顧 block作為屬性的格式: `@property (nonatomic, strong) void(^finishedCallback)(NSString *)`; block作為參數的定義格式:` (void (^)(NSString * str))finishedCallback` 3.閉包的格式: (參數列表) -> (返回值類型) 4.閉包的使用
5.尾隨閉包
1 // 尾隨閉包 : 如果函數的最後一個參數是一個閉包.那麼可以將函數調用寫成尾隨閉包 2 //就是把閉包寫到()的後面, 本來是寫在()裡面的 3 tools?.loadData() { (result) in 4 print("在ViewController中獲取到數據:\(result)") 5 } 6 7 // 如果函數有且只有一個參數,並且是一個閉包, 那麼()也可以省略 8 tools?.loadData { (result) in 9 print("在ViewController中獲取到數據:\(result)") 10 }
6.閉包的循環引用 6.1 一般在定義工具類的時候,會在工具類的方法中用到閉包 6.2 當工具類對閉包有強引用,一個控制器又調用包含該閉包的方法,在閉包方法中使用控制器的屬性,就會發生循環引用 6.3 控制器調用方法,就會對工具類有一個強引用, 閉包又拿到控制器的屬性,閉包對象就對控制器有一個強引用 6.4 在內存中就相當於這種表現
7.怎麼解決閉包的循環引用 與oc中類型,只需要把閉包對控制器的引用改為弱引用 8.怎麼改? 當閉包修改控制器的屬性時,拿到控制器的屬性時,把self(控制器)改成weakself即可 weak var weakself : ViewController? = self 五.swift項目的目錄結構簡介 1.swift項目目錄中沒有.h和.m的文件, 只有一個.swift的文件,相當於 2.swift目錄中.swift文件就相當於oc中的.h和.m文件 3.在swift中,調用項目中的其他源文件不需要導入頭文件 (一個 .swift文件就是一個源文件) 六.懶加載 1.懶加載的介紹 1.1 和OC中不同,swift有專門的關鍵字實現懶加載 1.2 懶加載本質:當第一次使用時再加載,而且只會被加載一次 2.swift中用lazy關鍵字來實現懶加載 2.1 懶加載格式
lazy var 變量: 類型 = { 創建變量代碼 }()= 後面是一個閉包 蘋果推薦用閉包來實現懶加載,可在閉包中對變量屬性進行初始化 2.2 懶加載的使用
1 lazy var names : [String] = { 2 return ["why", "yz", "lmj"] 3 }()
當執行到上面代碼的時候,names不會被加載到內存中, 當names第一次使用時,才會被加載
無論names使用多少次,只會被加載一次,也就是說內存中只有一個names屬性地址 七.swift中的常見注釋 1.單行注釋 和OC中的單行注釋一樣 使用 // 注釋內容 2.多行注釋 和OC中的多行注釋格式一樣 /* 注釋內容 */ 不同的是,swift中多行注釋可以嵌套使用 3.文檔注釋 與oc中不一樣 , swift中 用 /// 注釋內容 來實現文檔注釋 4.分組注釋 和oc不一樣 oc: #pragma mark - 注釋內容 swift: //MARK : - 注釋內容 八.訪問權限 1.internal :內部的 1.1 當不指定具體的訪問權限時,默認為internal 1.2 internal的訪問權限: 在當前項目(包)的任何地方都能訪問 2.private : 私有的 private的訪問權限: 在當前源文件中能夠訪問 一個 .swift文件就是一個源文件 3.public :公共的 3.1 public的訪問權限 : 可以跨包訪問 3.2 包的概念: 就是一個項目或一個框架 UIKit也是一個框架 九.異常處理 1.在swift中,如果一個方法的最後有一個throws,那麼這個方法能拋出異常 正則表達式就能拋出異常: NSRegularExpression(pattern: <#T##String#>, options: <#T##NSRegularExpressionOptions#>) 2.如果一個方法拋出異常,必須要對異常進行處理,否則編譯報錯 3.異常處理的三種方式 3.1 try : 手動處理異常,可以拿到異常(error) 要在方法前面加上try 而且外面要用do 包裝//try方式 --> 手動處理異常, 並且可以獲取到最終的異常結果 do { //如果有異常error有值 let regex = try NSRegularExpression(pattern: "", options: .CaseInsensitive) } catch { //通過error拿到異常結果 print(error) }
3.2 try? : 系統處理異常 try?方式 : 如果有異常,則返回nil,如果沒有異常,則返回結果 結果(regex)為可選類型 let regex = try? NSRegularExpression(pattern: "", options: .CaseInsensitive) regex?.matchesInString("", options: [], range: NSMakeRange(0, 0)) 3.3 try! :告訴系統不可能有異常 try!方式(不推薦) 注意:一旦發生異常,程序就會崩潰 let regex = try! NSRegularExpression(pattern: "", options: .CaseInsensitive) 十.如何拋出異常 1.在方法參數的後面加上 throws ,一定要有返回值 2.在某些具體的情況下拋出異常 比如:傳的參數不對等等 ,內部要對參數進行判斷 3.拋出的異常,一般定義為枚舉類型 枚舉後面要跟上 ErrorType 這種類型
十一.OC和swift相互調用 1.swift中調用oc 1.1 創建一個橋接文件 (.h的文件) 文件名一般為 Bridge.h 1.2 在橋接文件中導入oc的頭文件 1.3 配置橋接文件 工程 —> BuildSetting —> 搜索bridging 在後面寫入Bridge.h 的相對路徑
2.oc中調用swift 2.1 項目名稱要規范 (不能有中文和特殊字符) 2.2 swift中的類,屬性,方法名 前面要加 public 2.3 在oc文件中導入 工程名-Swift.h 的頭文件 工程名-Swift.h 系統會自動生成