defer
修飾函數(shù)內(nèi)任意一段代碼,調(diào)用時機(jī);在函數(shù)中其余代碼都執(zhí)行完畢销睁,函數(shù)即將結(jié)束前浑吟,可以用它在異常中進(jìn)行掃尾工作,比如關(guān)閉IO流釋放資源等
extension
通過增加的實例方法可以修改實例本身垦缅,如果結(jié)構(gòu)體和枚舉的方法要修改self或其屬性,則需要使用mutating關(guān)鍵字標(biāo)明
擴(kuò)展可以向已存在的類結(jié)構(gòu)體和枚舉添加新的嵌套類型
在結(jié)構(gòu)體、枚舉蹈丸、或者協(xié)議中使用mutating修飾方法可以在該方法內(nèi)部修改結(jié)構(gòu)體,枚舉呐芥,協(xié)議的屬性變量
對值類型進(jìn)行擴(kuò)展時白华,可以使用mutating修飾方法,使得方法內(nèi)部可以直接修改當(dāng)前實例的本身
屬性:不可以設(shè)置默認(rèn)值贩耐,必須設(shè)置{get}或{get set},必須設(shè)置為var
方法:可以定義普通方法弧腥,也可以定義mutating方法,方法不能有方法體潮太,方法的參數(shù)不能有默認(rèn)值
@objc
1管搪、selector中調(diào)用的方法需要在方法名前聲明@objc虾攻,目的是允許這個函數(shù)在運(yùn)行時通過Object_C的消息機(jī)制調(diào)用
2、協(xié)議的方法可選時更鲁,協(xié)議和方法前都要使用@objc聲明
3霎箍、用weak修飾協(xié)議時,協(xié)議前面要加@objc聲明
4澡为、類前加上@objcMembers漂坏,那么這個類及其子類擴(kuò)展里的方法都會隱士的加上@objc,如果不想加也可以用@nonobjc修飾
5媒至、擴(kuò)展前加上@objc那么里面的方法都會隱士的加上@objc
@objcMembers
在類名前面是使用objcMembers修飾顶别,系統(tǒng)會在自動給這個類的所有方法添加@objc,暴露給OC
OC和Swift中字符串的區(qū)別
OC中字符串是對象拒啰,性能略差
Swift中字符串是結(jié)構(gòu)體驯绎,性能更高
String支持直接遍歷
OC和Swift中數(shù)組的區(qū)別
Array是一個結(jié)構(gòu)體,NSArray是一個類
Array可以存放普通類型
reverse()數(shù)組倒序
只有相同數(shù)據(jù)類型的數(shù)組才能合并
class和static的比較
class和static的相同點(diǎn)
可以修飾方法谋旦,static修飾方法是靜態(tài)方法剩失,class修飾方法是類方法
都可以修飾計算屬性
class與static的不同點(diǎn)
class不能修飾存儲屬性,static可以修飾存儲屬性册着,static修飾的存儲屬性成為靜態(tài)變量(常量)
class修飾的計算屬性可以被重寫拴孤,static修飾的計算屬性不能被重寫
static修飾的靜態(tài)方法不能被重寫,class修飾的類方法可以被重寫
class修飾的類方法被重寫時甲捏,可以使用static讓方法變成靜態(tài)方法
class修飾靜態(tài)屬性被重寫時可以使用static讓其變?yōu)殪o態(tài)屬性但是他的子類就不能被重寫了
class只能在類中使用演熟,但static可以在類 結(jié)構(gòu)體 和枚舉中使用
值類型與引用類型
結(jié)構(gòu)體、枚舉是值類型摊鸡,類是引用類型
不同于值類型绽媒,引用類型被賦值到一個常量,變量或者本身被傳遞到一個函數(shù)的時候免猾,他是不會被拷貝的是辕,而是使用同一個對某個實例的引用
因為類是引用類型,可能有很多常量和變量都是引用到了同一個類的實例猎提,有時候需要判斷兩個常量或變量是否引用自同一個實例获三,Swift提供了兩個特征運(yùn)算符來檢查兩個常量或變量是否引用相同的實例
相同于:(===) 不同于:(!==)
重寫父類方法要在前面添加override,防止被重寫可以使用final標(biāo)記 final var final func final class func
Swift中的結(jié)構(gòu)體包含枚舉是值類型锨苏,它在代碼傳遞的過程中總是會被拷貝
CGRect CGSize CGPoint
字符串 字典 數(shù)組的賦值與拷貝
Swift中String疙教、Array、Dictionary類型是作為結(jié)構(gòu)體來實現(xiàn)的伞租,這意味著String贞谓、Array、Dictionary他們在賦值到一個新的常量或者變量或他們本身被傳遞到一個函數(shù)或者方法中的時候其實是傳遞了拷貝
OC中的NSString葵诈、NSArray裸弦、NSDictionary他們是作為類來實現(xiàn)的
類與結(jié)構(gòu)體的對比
相同點(diǎn):
定義屬性
定義方法
定義構(gòu)造函數(shù)
可以被擴(kuò)展
遵循協(xié)議
類有而結(jié)構(gòu)體沒有的額外功能
繼承
類型轉(zhuǎn)換
析構(gòu)函數(shù)
引用計數(shù)
類是引用類型 結(jié)構(gòu)體是值類型
內(nèi)存管理
內(nèi)存有兩個區(qū)域祟同,棧區(qū)stack 和堆區(qū)heap 在Swift中值類型存放在棧區(qū),引用類型存放在堆區(qū)
值類型理疙,即每個實例都保持一份數(shù)據(jù)拷貝晕城,值類型的賦值為深拷貝,即新對象和原對象是獨(dú)立的
引用類型窖贤,即所有實例共享一分?jǐn)?shù)據(jù)拷貝砖顷,在Swift中類和閉包都是引用類型,引用類型的賦值是淺拷貝赃梧,新對象和源對象的變量名不同但其引用指向的內(nèi)存空間是一樣的當(dāng)對新對象操作其內(nèi)部數(shù)據(jù)時滤蝠,原對象也會受到影響
inout
是Swift關(guān)鍵字,可以放置于參數(shù)類型之前冒號之后槽奕,使用inout之后几睛,函數(shù)體內(nèi)部可以直接更改參數(shù)值房轿,而且改變會保留
值類型變量作為參數(shù)傳入函數(shù)粤攒,外界和函數(shù)參數(shù)的內(nèi)存地址一致,函數(shù)內(nèi)對參數(shù)的更改得到了保留
使用inout注意事項:
使用inout關(guān)鍵字的函數(shù)囱持,在調(diào)用時需要在該參數(shù)前面加上&符號
inout 參數(shù)在傳入時必須為變量夯接,不能為常量或字面量
inout 參數(shù)不能有默認(rèn)值,不能為可變參數(shù)
inout 參數(shù)不等同于函數(shù)的返回值纷妆,是一種使參數(shù)的作用域超出函數(shù)體的方式
多個inout 參數(shù)不能傳入同一變量盔几,因為考入考出的順序不定,那么最終的值也無法確定
inout參數(shù)的傳遞過程:
1掩幢,當(dāng)函數(shù)被調(diào)用時逊拍,參數(shù)值被拷貝
2,在函數(shù)體內(nèi)际邻,被拷貝的參數(shù)修改
3芯丧,函數(shù)返回時,被拷貝的參數(shù)值給原有的變量
閉包
閉包能夠捕獲和存儲定義在其上下文中的任何常量和變量世曾,即閉合并包裹那些常量和變量
閉包和函數(shù)一樣也是引用類型缨恒,不是值類型
{(parameters) -> (return type) in
statements
}
閉包可以從上下文環(huán)境中捕獲變量常量,并在自己作用域內(nèi)使用
Swift最簡單的閉包形式是嵌套函數(shù)轮听,也就是定義在其他函數(shù)的函數(shù)體內(nèi)的函數(shù)骗露,嵌套函數(shù)可以捕獲其外部函數(shù)所有的參數(shù)以及定義的常量和變量
尾隨閉包,函數(shù)的最后一個參數(shù),網(wǎng)絡(luò)請求的處理
逃逸閉包血巍,閉包作為一個參數(shù)傳遞給一個函數(shù)
傳入函數(shù)的閉包如果在函數(shù)執(zhí)行之后才會被調(diào)用萧锉,那么這個閉包就叫逃逸閉包
逃逸閉包會在函數(shù)結(jié)束后才執(zhí)行,閉包可以超出函數(shù)的范圍來調(diào)用
一種自動創(chuàng)建的閉包述寡,用于包裝函數(shù)的表達(dá)式柿隙,不接受任何參數(shù)玫恳,被調(diào)用時會返回被包裝在其中的表達(dá)式的值,在形式參數(shù)
Swift中解決循環(huán)引用的方式
方案一:
使用weak 优俘,對當(dāng)前控制器使用弱引用
因為self可能有值也可能沒有值京办,因此weakself是一個可選類型,在真正使用時可以對weakself強(qiáng)制解包(強(qiáng)解包沒有問題帆焕,因為控制器一定存在否則無法調(diào)用所在的函數(shù))
方案二:
使用[weak self] 可以寫在閉包中惭婿,這樣用到的self都是弱引用
方案三:
使用關(guān)鍵字 unowned
unowned像OC中的unsafe_unretained
unowned表示:即使它原來的引用被釋放掉了,仍然會保持對被已經(jīng)釋放的對象的一個無效的引用叶雹,它不能是Optional值财饥,也不會被指向nil
使用Codable協(xié)議,通過解碼和編碼實現(xiàn)json與model之間的互轉(zhuǎn)
處理異常的三種方式
1折晦、do try catch方式钥星,手動處理異常(建議使用)
2、try? 方式满着,不處理異常谦炒,如果出現(xiàn)了異常,則返回一個nil,沒有異常則返回對應(yīng)的值
3风喇、try! 方式宁改,告訴系統(tǒng)該方法沒有異常,如果出現(xiàn)異常魂莫,會導(dǎo)致程序直接崩潰
typealias
是指類型別名还蹲,將一個已存在的類型名稱改為其他名字
好處:很好的標(biāo)示業(yè)務(wù),而不僅僅是全篇的基本類型耙考,方便統(tǒng)一類型管理
typealias NetParams = [String: Any]//網(wǎng)絡(luò)請求參數(shù)
開源框架多平臺統(tǒng)一類型谜喊,或者條件編譯統(tǒng)一類型
使用別名定義閉包,減少代碼長度倦始,方便閱讀
參數(shù)的兩種傳遞方式
1斗遏、值傳遞,傳遞的是參數(shù)的一個副本楣号,這樣在調(diào)用參數(shù)的過程中不會影響原始數(shù)據(jù)
2最易、指針傳遞,把參數(shù)本身引用的內(nèi)存地址傳遞過去炫狱,在調(diào)用過程中會影響原始數(shù)據(jù)
在Swift眾多數(shù)據(jù)類型中藻懒,只有class是指針傳遞,其余的如Int Float Bool Character Array Set enum struct 全都是值傳遞
如果要實現(xiàn)讓值傳遞變成指針傳遞视译,通過一個函數(shù)改變函數(shù)外部變量的值(將一個值類型以引用的方式傳遞)嬉荆,這時 Swift提供的inout關(guān)鍵字就可以實現(xiàn)
即聲明函數(shù)時,在參數(shù)前面加inout 修飾酷含,函數(shù)內(nèi)部改變外部參數(shù)時鄙早,在變量名前面使用&符號修飾表示汪茧,表明這個變量在參數(shù)內(nèi)部是可以改變的(可將改變傳遞到原始數(shù)據(jù))
注意:??inout修飾的參數(shù)是不能有默認(rèn)值的,有范圍的參數(shù)集合也不能被修飾 一個參數(shù)一旦被inout修飾了限番,就不能再被var和let修飾了
1舱污、監(jiān)測屬性,其實是給存儲屬性上添加的一種監(jiān)測功能弥虐,willSet監(jiān)測新值 didSet監(jiān)測舊值
2扩灯、如果函數(shù)的參數(shù)是inout修飾的,你如果將監(jiān)控的屬性傳入這個函數(shù)的時候霜瘪,此時會將屬性的值拷貝一份珠插,在函數(shù)調(diào)用結(jié)束之后將值新賦給屬性,所以函數(shù)執(zhí)行完畢會出發(fā)監(jiān)測方法