簡介
- Swift 語言由蘋果公司在2014年推出帮孔,用來撰寫 macOS 和 iOS 應(yīng)用程序
Swift 語言學(xué)習(xí)路線及重難點
- 常量與變量
- 數(shù)據(jù)類型
- 運算符
- 元組
- 邏輯分支
- 循環(huán)
- 字符串
- 數(shù)組
- 字典
- 可選型 (重點)
- 類型轉(zhuǎn)換(轉(zhuǎn)化符號is和as)
- 函數(shù)
- 閉包
- 枚舉
- 結(jié)構(gòu)體
- 類
- 屬性與方法
- 構(gòu)造與析構(gòu)函數(shù)
- 協(xié)議 protocol
- 擴展 extension
- 泛型
- 異常 和 Result
- 元類型镀迂、.self 與 Self
- @objc關(guān)鍵字
- where關(guān)鍵字
- Key Path
- Codable協(xié)議
- 訪問權(quán)限
- 混合開發(fā)
- 命名空間
- 學(xué)習(xí)參考
常量與變量
什么是常量和變量
- 常量:使用
let
定義屁柏,定義后不可修改 - 變量:使用
var
定義,定義后可以修改
常量和變量的使用注意
- 在開發(fā)中扑毡,建議先定義常量胃榕,如需修改再修改為變量(更加安全)
- 聲明為常量不可修改的意思是 指針不可以再指向其他對象,但是可以通過指針拿到對象瞄摊,修改其中屬性
數(shù)據(jù)類型
- Swift中的數(shù)據(jù)類型有:整型/浮點型/Bool型/元組/枚舉/結(jié)構(gòu)體/對象類型等
類型推導(dǎo)
- Swift是強類型語言勋又,是一種總是強制類型定義的語言,要求所有變量都必須先定義后使用
- 注意:
- 定義一個標(biāo)識符時有直接進行賦值换帜,標(biāo)識符后面的類型可以省略
- Swift有類型推導(dǎo)楔壤,會自動根據(jù)后面的賦值來決定前面的標(biāo)識符的數(shù)據(jù)類型
運算符
常見的運算符
- +、-膜赃、*挺邀、/揉忘、%
- =跳座、+=、-=泣矛、*=疲眷、/=、%=
- >您朽、>=狂丝、<、<=哗总、==几颜、!=
- 區(qū)間運算符
- 半開半閉區(qū)間:0..<10 表示0~9
- 閉區(qū)間:0...10 表示0~10
- &&、||讯屈、!
元組
- 元組:一種數(shù)據(jù)結(jié)構(gòu)蛋哭,可以用于定義一組數(shù)據(jù),組成元祖的數(shù)據(jù)可以稱為“元素”
// 元組的常見寫法
var one = ("李四", 30, 1.75)
var two = (name:"李四", age:30, height:1.75)
let (errorCode, errorInfo) = (404, "Not Found")
邏輯分支
// if 的使用
if a > 9 {
print(a)
}
// guard 的使用
guard 條件表達式 else {
// guard是Swift2.0新增的語法涮母,跳轉(zhuǎn)語句一般是return谆趾、break、continue叛本、throw
}
語句組
switch 分支
- 一個case判斷沪蓬,可以判斷多個值,以 , 隔開
- 如需case穿透来候,使用關(guān)鍵字
fallthrough
- 支持區(qū)間判斷和多種數(shù)據(jù)類型跷叉、浮點型、字符串類型等
循環(huán)
for 循環(huán)
// for in 循環(huán)
for i in 0..<10 {
print(i)
}
// 特殊寫法 如不需要用下標(biāo)i
for _ in 0...10 {
print("hello swift")
}
while 和 repeat while 循環(huán)
var a = 0
while a < 10 {
a = a + 1
}
var b = 0
repeat {
b = b + 1
} while b < 20
字符串
- String是一個結(jié)構(gòu)體,NSString是OC對象云挟,String性能更高
- String支持直接遍歷
字符串常用操作
// 1峡眶、拼接 使用 + 或 append
let str = "abc" + "def"
// 2、遍歷
for (index, value) in str.enumerated() {
print("\(index) --- \(value)")
}
// 3植锉、大寫或小寫
str.lowercased().uppercased()
// 4辫樱、含有字符串
str.contains("cd")
// 5、分割
let str1 = "aa&$$bb$$cc$$dd"
let desc = str1.components(separatedBy: "$$")
// 6俊庇、替換
let desc1 = str1.replacingOccurrences(of:"$$", with:"**")
// 7狮暑、子串
str.prefix(5) // 截取前5個字符
str.suffix(5) // 截取后5個字符
str.index(str.startIndex, offsetBy: -2)
let sub1 = str[0..<5] // 從位置0開始到5結(jié)束獲取字符串
數(shù)組
- 數(shù)組是一堆有序的由相同類型元素構(gòu)成的集合
- 數(shù)組中的元素是有序的,可重復(fù)出現(xiàn)
- Swift中用Array表示數(shù)組辉饱,是一個結(jié)構(gòu)體搬男,可以放普通類型
// 定義
var array = ["zhangsan", "lisi", "wangwu"]
// 基本操作
array.count // 獲取長度
array.isEmpty // 判空
array.append("l") // 添加數(shù)據(jù)
array.insert("wo", at:0) // 插入元素
array.dropFirst() // 刪除元素
array[0] = "fangqi" // 修改元素
array.reverse() // 倒序
// 遍歷
for (index, name) in array.enumerated() {
print(index)
print(name)
}
字典
// Swift中任意類型用Any表示,如下定義字典
var dict: [String:Any] = ["name":"張三", "age":18]
// 基本操作
dict.count // 獲取長度
dict.isEmpty // 判空
dict["height"] = 1.82 // 添加數(shù)據(jù)
dict.removeValue(forKey: "height") // 刪除字段
dict["name"] = "lisi" // 修改字典 或使用 dict.updateValue("lisi", forKey:"name")
// 遍歷
for (key, value) in dict {
print("\(key) --- \(value)")
}
可選型 (重點)
- 可選類型(Optional)的取值為:有值 | nil
// 定義可選類型
let name: String? = nil
// 取出可選類型的值 ! 強制解包(顯示解包)
print(name!) // 如果可選類型為nil彭沼,會報錯
// 可選綁定(隱式解包)
if let str = name {
print(str) // 此時輸出就是str的值缔逛,而不是Optional
}
// 或使用guard取出可選類型的值
guard let str = name else {
return
}
print(str)
類型轉(zhuǎn)換
類型轉(zhuǎn)化符號 is 和 as
// 定義數(shù)組
let array: [Any] = [12, "zhangsan"]
// 取出數(shù)組中最后一個元素
let objcLast = array.last!
// is 判斷元素是否是一個Int類型
if objcLast is Int {
print("是Int類型")
}
// as? 將Any轉(zhuǎn)成可選類型,通過判斷可選類型是否有值姓惑,來決定是否轉(zhuǎn)化成功了
let name = objcLast as? String
print(name) // 結(jié)果:Optional("zhangsan")
// as! 將Any轉(zhuǎn)成具體的類型褐奴,如果不是該類型,那么程序會崩潰
let name2 = objcLast as! String
print(name2) // 結(jié)果:zhangsan
Any于毙、AnyObject
- Any是一個空協(xié)議集合的別名敦冬,它表示沒有實現(xiàn)任何協(xié)議,因此它可以是任何類型唯沮,包括類實例與結(jié)構(gòu)體實例脖旱。可以表示任何類型介蛉,包括函數(shù)類型
- AnyObject是一個成員為空的協(xié)議辛藻,任何對象都實現(xiàn)了這個協(xié)議伴挚。可以表示任何類類型的實例
函數(shù)
func 函數(shù)名(參數(shù)列表) -> 返回值類型 {
return 返回值
}
函數(shù)的使用注意
- 函數(shù)參數(shù)沒有用var和let修飾,但它是常量桥氏,不能在函數(shù)內(nèi)修改
- 每個函數(shù)的形式參數(shù)都包含形式參數(shù)標(biāo)簽和形式參數(shù)名兩部分
- 某些情況青灼,如果沒傳入具體的參數(shù)卷仑,可以使用默認(rèn)參數(shù)
- 可變參數(shù)孽尽,可接受不確定數(shù)量的參數(shù),必須有相同的類型
- 默認(rèn)函數(shù)參數(shù)是值傳遞毁葱,如想改變外面變量垫言,使用
inout
關(guān)鍵字 - 函數(shù)的嵌套,不推薦該寫法
函數(shù)類型
- 函數(shù)是 引用類型
- 每個函數(shù)都有屬于自己的類型倾剿,由函數(shù)的 參數(shù)類型 和 返回類型 組成
- 有了函數(shù)類型筷频,就可以把函數(shù)類型像Int蚌成、Double、Array來用凛捏,比如函數(shù)類型 (Int, Int) -> Int
閉包
// 閉包表達式
{ (parameters) -> (return type) in
statements
}
- 閉包表達式由一對 {} 開始與結(jié)束
- 由 in 關(guān)鍵字將閉包分割成兩部分:參數(shù)與返回值担忧、閉包體
- 閉包形參不能提供默認(rèn)值
閉包參數(shù)名稱縮寫
let array = getList(score: [65,75,85,95], op: { (num: Int) -> Bool in return num>80 })
// 簡寫一:省略 -> 與返回值類型
let array1 = getList(score: [65,75,85,95], op: { (num: Int) in return num>80 })
// 簡寫二:省略參數(shù)類型和括號
let array2 = getList(score: [65,75,85,95], op: { num in return num>80 })
// 簡寫三:省略 return 關(guān)鍵字
let array3 = getList(score: [65,75,85,95], op: { num in num>80 })
// 簡寫四:參數(shù)名稱縮寫,省略參數(shù)聲明和 in坯癣,改為$0
let array4 = getList(score: [65,75,85,95], op: { $0>80 })
捕獲
- 閉包可以在上下文環(huán)境中捕獲常量瓶盛、變量、并在自己的作用域內(nèi)使用
- Swift最簡單的閉包形式是嵌套函數(shù)示罗,可以捕獲其外部函數(shù)所有的參數(shù)以及定義的常量和變量
尾隨閉包
- 是一個寫在函數(shù)括號之后的閉包表達式惩猫,函數(shù)支持將其做為最后一個參數(shù)調(diào)用
func doSomething(info: String, clousre: (String) -> Void) {
clousre(info)
}
// 使用尾隨閉包進行函數(shù)調(diào)用
doSomething(info: "World") { s in
print(s)
}
逃逸閉包
- 閉包作為一個參數(shù)傳遞給一個函數(shù)
- 傳入函數(shù)的閉包如果在函數(shù)執(zhí)行結(jié)束后才會調(diào)用,那就叫做逃逸閉包
- 聲明閉包作為形參的函數(shù)時蚜点,可以在形參的類型之前寫上
@escaping
來明確閉包是允許逃逸的 - 逃逸閉包會在函數(shù)結(jié)束后才執(zhí)行
自動閉包
- 一種自動創(chuàng)建的閉包轧房,用于包裝函數(shù)參數(shù)的表達式
- 不接受任何參數(shù),被調(diào)用時會返回被包裝在其中的表達式的值
- 在形參的類型之前加上
@autoclosure
關(guān)鍵字標(biāo)識是一個自動閉包
Swift中閉包在官方系統(tǒng)庫中的應(yīng)用函數(shù)
- sort —— 排序
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 這種默認(rèn)升序
array.sorted()
// 如果需要降序
array.sort { (str1, str2) -> Bool in
return str1 > str2
}
- forEach —— 遍歷
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 遍歷
array.forEach { (str) in
print(str)
}
- filter —— 篩選
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 篩選
let a = array.filter { (str) -> Bool in
str.starts(with: "A")
}
- map —— 變換
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
// 閉包返回一個變換后的元素绍绘,接著組成一個新數(shù)組
let a = array.map { (str) -> String in
"Hello " + str
}
- reduce —— 合歸
var sum:[Int] = [11, 22, 33, 44]
var total = sum.reduce(0) { (result, num) -> Int in
return result + num
}
- allSatisfy —— 條件符合
// 判斷數(shù)組的所有元素是否全部大于85
let scores = [86, 88, 95, 92]
// 檢查序列中的所有元素是否滿足條件奶镶,返回Bool
let passed = scores.allSatisfy { $0 > 85 }
- compactMap —— 轉(zhuǎn)換
let arr: Array = [1, 2, 34, 5, 6, 7, 8, 12, 45, 6. 9]
// 返回操作的新數(shù)組(并不是篩選),數(shù)組陪拘,字典都可以使用
let compact = arr.compactMap({ $0%2 == 0})
- mapValues —— 轉(zhuǎn)換value
let dic = ["first":1, "second":2, "three":3, "four":4]
// 字典中的函數(shù)厂镇,對字典的value執(zhí)行操作,返回改變value后新的字典
let mapValues = dic.mapValues({ $0 + 2 })
- compactMapValues —— 上面兩個的合并
let dic = ["first":1, "second":2, "three":3, "four":4, "five":"abc"]
// 將上述兩個方法的功能合并在一起藻丢,返回一個對value操作后的新字典剪撬,并且自動過濾不符合條件的鍵值對
let newDic = dic.compactMapValues({Int($0)})
first(where:) —— 篩選第一個符合條件的
last(where:) —— 篩選最后一個符合條件
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
let elementF = array.first(where: { $0.hasPrefix("A") })
let elementL = array.last(where: { $0.hasPrefix("A") })
removeAll(where:) —— 刪除
// 高效根據(jù)條件刪除摄乒,比filter內(nèi)存效率高悠反,指定不想要的東西
var array: [String] = ["Animal", "Baby", "Apple", "Google", "Aunt"]
array.removeAll(where: { $0.hasPrefix("A") })
枚舉
Swift中的枚舉是一等類型,它可以像類和結(jié)構(gòu)體一樣增加 屬性和方法
枚舉定義
enum Sex {
case male
case female
}
枚舉賦值
- 枚舉類型賦值可以是字符串/字符/整型/浮點型
- 如果有給枚舉類型賦值馍佑,則必須在枚舉類型后面明確具體類型
枚舉類型推斷
- 如果枚舉類型確定了斋否,在訪問值的時候可以用 .值 來訪問
枚舉原始值
- 原始值區(qū)分大小寫
- 通過
rawValue
可以獲取原始值 - 通過
rawValue
返回的枚舉是一個可選型,因為原始值對應(yīng)的枚舉不一定存在 - 如果指定第一個元素的原始值后拭荤,后面元素原始值默認(rèn)+1茵臭,枚舉一定是Int類型
枚舉遍歷
enum Method: CaseIterable {
case Add, Sub, Mul, Div
}
for method in Method.allCases {
print(method)
}
枚舉的可選參數(shù)
// Swift5之后,可變參數(shù)的枚舉定義時舅世,...改成了數(shù)組
enum ABC {
// case abc(argv: Int...)
case abc(argv: [Int])
}
func getABC() -> ABC {
return .abc(argv: [0, 1, 2, 3])
}
結(jié)構(gòu)體
- 結(jié)構(gòu)體(struct)是由一系列具有相同類型或不同類型的數(shù)據(jù)構(gòu)成的數(shù)據(jù)集合
- 結(jié)構(gòu)體是值類型(包括枚舉)它在代碼傳遞中總是會被拷貝
- 結(jié)構(gòu)體既可以定義屬性又可以定義方法
- 常用的結(jié)構(gòu)體比如:CGRect旦委、CGSize、CGPoint
字符串雏亚,數(shù)組和字典的賦值與拷貝行為
- Swift 中的String缨硝,Array 和 Dictionary 類型是作為結(jié)構(gòu)體來實現(xiàn)的,這意味著在它們被賦值到一個新的常量或變量罢低,或它們本身被傳遞到一個方法中查辩,其實是傳遞了拷貝胖笛。這里與OC中有明顯區(qū)別
類
- Swift雖然推薦面向協(xié)議編程,但其也是一門面向?qū)ο箝_發(fā)的語言
- 特征運算符
- 相同于(===)
- 不同于(!==)
- 繼承
- 重寫
override
- 防止被重寫
final
- 重寫
類與結(jié)構(gòu)體對比
- 相同點
- 定義屬性
- 定義方法
- 定義構(gòu)造函數(shù)(init函數(shù))
- 可以被擴展
- 遵循協(xié)議
- 類有而結(jié)構(gòu)體沒有的額外功能
- 繼承
- 類型轉(zhuǎn)換(子類 as 父類)
- 析構(gòu)函數(shù)
- 引用計數(shù)
屬性與方法
類的屬性介紹有多種
- 存儲屬性:存儲實例的常量和變量
- 計算屬性:依賴于存儲屬性宜岛,通過計算得出來长踊,它提供getter和setter間接訪問和設(shè)置值
- 類屬性:與整個類自身相關(guān)的屬性用static來修飾
- 懶加載屬性:用lazy修飾,必須進行初始化
總結(jié)
- 存儲屬性萍倡,最先被初始化
- 構(gòu)造方法身弊,僅次與存儲屬性調(diào)用,可以在這里對存儲屬性進行賦值
- 懶加載屬性列敲、類屬性佑刷、全局屬性都是在第一次使用的時候初始化一次,以后調(diào)用都不再初始化
- 當(dāng)懶加載屬性是基于一個存儲屬性計算的時候酿炸,切勿使用懶加載屬性瘫絮,采用計算屬性
監(jiān)聽屬性的改變
- Swift中可以通過屬性觀察者來監(jiān)聽和響應(yīng)屬性值的變化
- 定義觀察者
- willSet:在屬性值被存儲之前設(shè)置。此時新屬性值作為一個常量參數(shù)被傳入填硕。該參數(shù)名默認(rèn)為newValue麦萤,可以自定義
- didSet:在新屬性值被存儲后立即調(diào)用。與willSet相同扁眯,此時傳入的是屬性的舊值壮莹,默認(rèn)參數(shù)名為oldValue,可以自定義
- willSet與didSet只有在屬性改變時才會調(diào)用姻檀,在初始化時不會去調(diào)用這些監(jiān)聽的方法
值類型在實例方法中修改屬性和調(diào)用方法
- 值類型默認(rèn)情況下命满,不能在實例方法中修改屬性
- 不能用self調(diào)用其他的函數(shù)
- 可以在函數(shù)前方一個
mutating
關(guān)鍵字來實現(xiàn)
類方法
- 在函數(shù)前使用
static
關(guān)鍵字(能在類、結(jié)構(gòu)體中使用) - 在函數(shù)前使用
class
關(guān)鍵字(只能在類中使用)
class 和 static 總結(jié)
構(gòu)造與析構(gòu)函數(shù)
默認(rèn)構(gòu)造函數(shù)
- 默認(rèn)構(gòu)造函數(shù)就像一個沒有形參的實例方法绣版,使用
init
關(guān)鍵字來寫
自定義構(gòu)造函數(shù)
- 希望在創(chuàng)建一個對象時手動給屬性賦值(屬性的值是在外面?zhèn)鬟M去的)
- 自定義構(gòu)造函數(shù)和默認(rèn)構(gòu)造函數(shù)可以同時存在
Swift為類 類型定義了兩種構(gòu)造函數(shù)以確保所有存儲屬性接收一個初始值胶台,指定構(gòu)造函數(shù)和便捷構(gòu)造函數(shù)
- 指定構(gòu)造函數(shù)是類的主要構(gòu)造函數(shù),指定構(gòu)造函數(shù)可以初始化所有類引用的屬性杂抽,并且調(diào)用合適的父類構(gòu)造函數(shù)來繼續(xù)這個初始化過程給父類鏈
- 便捷構(gòu)造函數(shù)是次要的诈唬,可以在相同的類里定義一個便捷構(gòu)造函數(shù)來調(diào)用一個指定構(gòu)造函數(shù)給指定構(gòu)造函數(shù)設(shè)置默認(rèn)形式參數(shù)
// 類的指定構(gòu)造函數(shù)
init(parameters) {
statements
}
// 便捷構(gòu)造函數(shù)需用 convenience 修飾符放到 init 關(guān)鍵字前
convenience init(parameters) {
statements
self.init(parameters)
}
- 指定構(gòu)造函數(shù)必須總是向上委托
- 便捷構(gòu)造函數(shù)必須總是橫向委托
析構(gòu)函數(shù)
- 當(dāng)引用計數(shù)為0時,系統(tǒng)自動調(diào)用析構(gòu)函數(shù)
deinit
(不可手動調(diào)用)
協(xié)議 protocol
協(xié)議可被類缩麸、結(jié)構(gòu)體铸磅、或枚舉類型采納以提供所需功能的具體實現(xiàn)即遵循協(xié)議
擴展 extension
- 為現(xiàn)有的類、結(jié)構(gòu)體杭朱、枚舉類型阅仔、協(xié)議添加新功能。擴展和Objective-C中的分類類似
- Swift中使用
extension
關(guān)鍵字實現(xiàn)擴展
面向協(xié)議編程
針對某個需要實現(xiàn)的功能弧械,可以使用協(xié)議定義出接口八酒,然后利用協(xié)議擴展提供默認(rèn)的實現(xiàn),需要這個功能梦谜,只需要聲明遵守這個協(xié)議即可丘跌,遵守某個協(xié)議的對象調(diào)用協(xié)議聲明的方法時袭景,如果遵守者本身沒有提供實現(xiàn),協(xié)議擴展提供的默認(rèn)實現(xiàn)會被調(diào)用
泛型
類型約束 和 關(guān)聯(lián)類型
- 關(guān)聯(lián)類型通過
associatedtype
關(guān)鍵字指定
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}
protocol SomeProtocol {
associatedtype Element: Equatable
func method1(element: Element)
}
異常
// 1闭树、定義異常
enum FileReadError: Error {
case FileIsNull
case FileNotFound
}
// 2耸棒、讓方法拋出異常
func readFileContent(filePath: String) throws -> String {
if filePath == "" {
throw FileReadError.FileIsNull
}
if filePath != "/User/Desktop/123.plist" {
throw FileReadError.FileNotFound
}
return "123"
}
// 處理異常
do {
let result = try readFileContent(filePath: "abc")
} catch {
print(error) // 有一個隱藏參數(shù) error
}
// defer關(guān)鍵字
Result
- 在Swift5中,新增了一個枚舉類型Result报辱,使我們能夠更簡單与殃、更清晰處理復(fù)雜代碼中的錯誤
// 使用Result處理異常如下
func readFileContent(filePath: String) -> Result<String, FileReadError> {
if filePath == "" {
return .failure(.FileIsNull)
}
if filePath != "/User/Desktop/123.plist" {
return .failure(.FileNotFound)
}
return .success("123")
}
// 調(diào)用
let result = readFileContent(filePath: "")
switch result {
case .failure(let error)
print(error)
case .success(let content)
print(content)
}
元類型、.self 與 Self
- 獲取對象類型:
type(of: )
語法 - 元類型:可以理解為類型的類型碍现,可以通過
類型.Type
定義幅疼,可以修飾變量或常量,如何得到這種類型昼接?需要通過類型.self
- Self大寫在定義協(xié)議的時候用的頻率很高爽篷,用于協(xié)議中限制相關(guān)的類型
@objc關(guān)鍵字
出于安全的考慮,需將暴露給Objective-C使用的如類慢睡、屬性和方法的聲明前面加上@objc
- #selector 中調(diào)用的方法需要在方法前聲明
@objc
- 協(xié)議的方法可選時逐工,協(xié)議和可選方法前要用
@objc
聲明 - 用weak修飾的協(xié)議時 ,協(xié)議前面要用
@objc
聲明 - 類上加
@objcMembers
漂辐,則其及子類泪喊、擴展里的屬性和方法都會隱式的加上@objc
,如果部分不想加髓涯,可以用@nonobjc
修飾 - 擴展前加上
@objc
袒啼,那么里面的方法都會隱式加上@objc
where關(guān)鍵字
where關(guān)鍵字的含義和數(shù)據(jù)庫中差不多,用于條件篩選纬纪,在Swift中哪些地方用到蚓再,如下總結(jié)
- Switch case 分支
- for 循環(huán)
- protocol 協(xié)議
- Generic 泛型
- do catch 異常處理
Key Path
- 類似OC中的KVC
- 用于間接獲取/設(shè)置值
- 類必須繼承自NSObject,否則不能用
- 哪些屬性可以通過KeyPath操作育八,就需要在前面加上@objc
// Swift 3 之前
stu.value(forKey: "name")
stu.setValue("lisi", forKey: "name")
// Swift 3
stu.value(forKey: #keyPath(Student.sex))
stu.setValue("女", forKey: #keyPath(Student.sex))
// Swift 4
stu[keyPath: \Student.sex]
stu[keyPath: \Student.sex] = "女"
Codable協(xié)議
- JSON轉(zhuǎn)Model对途,以前可以利用KVC、NSJSONSerialization實現(xiàn)
- Swift 4之后推薦使用Codable協(xié)議髓棋,可以通過編碼和解碼實現(xiàn)互轉(zhuǎn)
訪問權(quán)限
-
open
和public
:允許被定義模塊中任意源文件訪問,也可以被另一模塊源文件通過導(dǎo)入該定義模塊來訪問 -
internal
:(默認(rèn))允許被定義模塊中的任意源文件訪問惶洲,但不能被該模塊之外的任何源文件訪問 -
fileprivate
:使用限制于當(dāng)前定義的原文件中 -
private
:使用限制于封閉聲明中按声,比fileprivate更嚴(yán)格
注意
- 訪問權(quán)限可以修飾 類、方法恬吕、屬性等
- 在Swift4中签则,private的屬性作用域擴大到extension中,也就是說在extension中訪問屬性可以是fileprivate或private修飾的
學(xué)習(xí)參考
- 持續(xù)關(guān)注Swift之后發(fā)布的新版本铐料,了解新特性渐裂,關(guān)注SwiftUI等
學(xué)習(xí)網(wǎng)址