素材:Language Guidehtml
初次接觸 Swift,建議先看下 A Swift Tour,不然思惟轉換會很費力,容易卡死或鑽牛角尖。算法
一樣是每一章只總結3個本身認爲最重要的點。這樣挺好!強迫你去思考去取捨。之後再看,也方便快速重建記憶。編程
注意: 我的筆記,僅供參考,不保證嚴格意義上的正確性。swift
* 整數,優先使用 Int,浮點數,優先使用 Double * 可使用 0b 表示二進制,能夠在數字中間插入可讀字符 _,如 182_3880_25 * as 僅用於兼容類型間的相互轉換.非兼容類型的轉換,由各個類本身的初始化方法實現.
* 空格對操做符的影響很大,如 a??b 應該寫做 a ?? b, 由於 a? 也是一個有效的操做符. * a ?? b 返回的是 a unwrap 後的值或 b 的值. ?? 比 js 的 || 好使多了,由於前者能準確區分零值和nil值.只有nil值時,才須要使用默認值. * names[0..<2] 本質上,是獲得了一個數組. ==> 本質上,應該是 array 的[]操做符,重載後,支持了 range 參數.
* 多行字符串的起始偏移,是根據末尾的 """ 的偏移 來斷定的. * collection 類型,都有本身的 index struct.String 中涉及的增刪改查操做,適用於全部 collection 類型. * SubString 的增刪改查,只是一個原有 String 上的遊標操做.
* collection type 是struct,是複製傳值,即便只是 a = b * 操做符重載以後,能夠支持數組相加(+)等操做,能夠顯著代碼的可讀性和簡潔性 * 能在編譯器推導出的模板類型部分,均可以省略實例類型部分
* switch case 匹配中的 range,也支持源於 String.index 的range * where 充當一個查詢子句的角色 * \#available的確可讓API可用性檢查,更方便.
* 可變字符串的 label 是能夠在函數聲明時,由本身指定的. ==> 可變參數,不須要是最後一組參數 * inout 有點像是指針傳值;不一樣的是,在函數內使用時,不須要處理指針解引用操做,直接一個普通 var 變量使用便可. * 參數默認是 let 不可變類型,不容許修改
* function type 不包含 label 部分 --> 傳遞function時,其label部分會被自動忽略. --> 在絕大部分場景中,兩者是兼容的. * closure 能夠省略參數類型,是由於類型推導機制的存在 --> 尾閉包,能夠省略 (); * 用做函數參數的閉包,若是想在函數外使用,須要額外加 @escaping 標記 ;@autoclosure 會自動補全用做函數參數的閉包的{}符號 --> @autoclosure 標記的閉包,是有可能和其餘通常參數標記的參數,函數簽名重複的.
* 遞歸定義的枚舉,就是一個演示函數式編程的絕佳示例. * swift 中的枚舉,變成了一中,能夠有效承載數據和算法的描述性數據結構. * swift 中的 enumeration ,極有可能成爲一種新的 Model 載體.
* 可選變量,的確會被自動初始化爲 nil. * swift 中,能夠設置組件的 frame 了.呼哈哈 label.frame.origin.x = 100. * String, Array, and Dictionary 居然是在swift中被實現爲結構體了,值傳遞.
* lazy 關鍵字實現的屬性懶加載,果真比重寫 getter 方法,要清晰簡潔好多啊. * 能夠用 static 或 class 聲明類變量/類方法; 用class 聲明的類變量或類方法,支持子類重寫其實現. * [self class] 等價寫法是: type(of: self).
* 結構體實例中,方法是否可以修改屬性,也受實例自己的可變性的影響. * 結構體或枚舉等值類型,容許在實例方法內,直接給 self 賦值,完整替換. * 枚舉類型的相關操做,均可以封裝在枚舉類型自身,這樣封裝性會更好.
* subscript 是一個新的語言特性,不是簡單的函數重寫. * subscript 能夠接收多個參數 * subscript 的參數和返回值,能夠徹底自定義
* 能夠經過 super 來使用父類方法或屬性. * 能夠在方法或屬性前加 final 關鍵字,來禁止被子類重寫. * 能夠在類前加 final 關鍵字,來禁止被繼承.
* deisingnated init 通常只調用父類 deisingnated init; convenience init 通常只調用同類的 desingnated init;deisingnated init 中,是不容許調用同級的另外一個deisingnated init;子類中,只容許調用父類的 designated init. * 調用父類初始化方法前,子類自有的 stored property 必須先所有初始化 --> super.init 若是不顯式調用, 系統會自動調用. 在調用 super.init 以前,不能調用任何實例方法,由於對象尚未效初始化. * 用 closure 指定默認值和屬性的get/set 方法的區別在於 聲明有個等號(=),說明前者是個賦值操做.
* 把變量置爲 nil,便可觸發 deinit. * deinit 執行順序: 子類 --> 父類. * 不能在子類 deinit 中調用 super.deinit.
* 在訪問 optional 對象的內部屬性時,必須使用 ? 或 ! 進行 unwrap 操做. * 賦值操做中,若是左側是要賦值給 optional 實例的某個屬性,則會先 unwrap optional 實例,若是不爲nil,纔會計算右側的表達式. * 鏈式語法中,有一個 optional 調用(X?),則返回值必然是 optional 的.
* 函數A中,能夠 try 函數B,若是函數B拋出錯誤,則會直接拋給 A 的調用者. * do-catch 中的catch 部分 和 switch-case 中的case部分,匹配方式很像. * try? 的做用是是將函數返回值轉換爲 optional 對象. try? 的返回值,有多是多層 optional,層數等於原函數返回值的 optional wrap 層數 + 1.try! 是保證不會拋出異常,若是有,就直接crash.
* is 近似於 isKind; 精確判斷時,能夠考慮使用 type(of: T1) == T2.self * 類型轉換用的是 as? 或 as!,用法習慣和 try? try! 相似. * 數組具體化類型聲明爲 Any / AnyObject 時,數組內可同時存放多種類型不兼容的實例.
* 支持類型嵌套定義,這已是很大的突破了. * 即便在函數內部,也能夠定義新的類型. * 能夠用.語法,訪問嵌套定義的類型.
* extensions 和 categories 的重要區別之一是,前者不須要寫名字. * extensions 不容許覆蓋已有方法,且不一樣 extentsion 中的方法簽名也不容許重複. * extentsion 擴展的東西,是能夠被子類繼承的.
* 在swift 的設定中, protocol 也屬於 type,能夠用於任何 type 適用的場景. * 在類型聲明遵循某協議之外的位置,書寫符合協議的方法是,用 & 鏈接多個協議,如 AP&BP&CP. * protocol 能夠在 extension 中定義本身的方法,任意遵循此協議的類型的實例均可以調用此協議本身的方法實現. --> 能夠在 extension 實現協議規定的屬性或方法的默認實現. -->能夠用 extension-where來指定,僅在特定條件下,纔有效的protocal自有協議方法.
* 泛型類型中的佔位類型,也能夠用於其自身的 extention 中. * 能夠用相似 <T: SomeClass> 或 <T: SomeAProtocol&SomeBProtocol> 或 where 子句 指定佔位類型自己須要知足的類型或協議約束. --> 藉助 associatedtype 關鍵字, protocol 也能夠支持泛型. * AnyObject 自己不能直接在類型定義時,聲明應遵循的協議的位置使用 --> 能夠先定義一個協議 A,繼承自 AnyObject,而後讓類型定義時聲明遵循協議 A,便可間接使用協議 AnyObject.
* optional 變量,也是強引用 -> 能夠繼續使用 weak 關鍵字聲明弱引用屬性或變量 -> unowned 與 weak 的區別是,前者不會自動置爲 nil. * closure 是引用類型 -> closure 內引用實例屬性,必須加 self前綴 -> closure 的參數聲明前,能夠加一個 capture list,如 [unowned self],來解決循環引用問題. * 能夠證實,在非 self 之外的狀況, closure 並不會引發內部使用變量的引用計數的變化.
* inout 標記的函數參數,是最容易引發訪問衝突問題的. * 往同一函數,同時以不一樣的 inout 參數,傳遞同一個實際變量,會引發訪問衝突 --> 這一行爲,能夠被自動識別並標記出來 * 類型方法調用,不容許使用自身做爲 inout 參數傳遞給本身的某個方法.
* 默認訪問級別是 internal,能夠在定義它的模塊內的各個源文件之間自由使用. * fileprivate 和 private 並存,是由於swift中容許類型嵌套定義. * 子類的訪問級別不能比父類更寬鬆;可是子類能夠經過重寫機制,使父類的成員的訪問級別變的更寬鬆.
* 重載操做符的語法是: static [prefix|infix|postfix] func 某個操做符 --> == 和 != 也能夠重載,來簡化等價判斷操做. * 複合操做符,要單獨重載,不會自動根據已有操做符自動推導,如 不會根據 + ,自動實現 +=. * 能夠基於已有操做符,聲明本身的操做符: prefix|infix|postfix operator 操做符,infix 二元操做符,要單獨聲明優先級,如 : infix operator +-: AdditionPrecedence.