private和fileprivate的區(qū)別
swift 面試題
https://blog.csdn.net/shihuboke/article/details/106388320
swift 與oC 的區(qū)別
http://www.itdecent.cn/p/158d65bc281e
- 結(jié)構(gòu)體調(diào)用方法時(shí),是直接call地址,而類(lèi)實(shí)例調(diào)用方法時(shí),則是通過(guò)偏移找到方法在vtable的位置,然后再call調(diào)用
- 經(jīng)過(guò)objc dynamic修飾的,方法調(diào)用objc_msgSend
swift onower 和weak的區(qū)別,onower什么情況下用
weak、unowned 都能解決循環(huán)引用的問(wèn)題
unowned 要比weak 少一些性能消耗
在生命周期中可能會(huì)變?yōu)?nil 的使用 weak,初始化賦值后再也不會(huì)變?yōu)?nil 的使用 unowned
相同點(diǎn): 引用對(duì)象的引用計(jì)數(shù)都不會(huì)加一,都不會(huì)對(duì)引用對(duì)象產(chǎn)生強(qiáng)引用
不同點(diǎn):weak的對(duì)象,在block塊內(nèi)再次獲取的時(shí)候是可選的,可能為nil,調(diào)用屬性或者方法需要加上?或者強(qiáng)制解析!,但是強(qiáng)制解析在對(duì)象已經(jīng)被釋放了時(shí)肯定會(huì)造成強(qiáng)解錯(cuò)誤,導(dǎo)致程序崩潰
unower的對(duì)象,在block塊內(nèi)再次獲取的時(shí)候依然是對(duì)象本身,非可選,因?yàn)橐欢ūWC在block塊內(nèi)再次獲取的時(shí)候?qū)ο笠廊淮嬖冢蝗徽{(diào)用屬性或者方法肯定會(huì)造成導(dǎo)致程序崩潰
另外,你還可以利用【生命周期】的長(zhǎng)短去理解,即分別在什么場(chǎng)景下使用unowned和weak:
unowned所在的block的生命周期務(wù)必要比unowned修飾對(duì)象的生命周期短,即block一旦銷(xiāo)毀了,也就不會(huì)再調(diào)用了,也就不存在修飾對(duì)象的引用問(wèn)題了。
weak所在的block可能要比weak修飾對(duì)象的生命周期長(zhǎng),block被調(diào)用時(shí),修飾對(duì)象可能已經(jīng)釋放掉了,此時(shí)通過(guò)修飾對(duì)象?去調(diào)用也就不會(huì)引發(fā)問(wèn)題,保證程序正常運(yùn)行。
什么時(shí)候使用 weak和unowned
- Weak和unowned引用都不會(huì)增加引用計(jì)數(shù),它們都能用于解除引用循環(huán)。
- 在引用對(duì)象的生命周期內(nèi),如果它可能為nil,那么就用weak引用。反之,當(dāng)你知道引用對(duì)象在初始化后永遠(yuǎn)都不會(huì)為nil就用unowned.
進(jìn)行判斷使用class_深入理解Swift中的Class和Struct
Swich
- Switch 默認(rèn)可以不寫(xiě)break,并不會(huì)貫穿到后面的條件
- 使用fallthrough可以實(shí)現(xiàn)貫穿效果
- switch必須要保證能處理所有情況
- case、default后面至少要有一條語(yǔ)句,如果不想做任何事,加個(gè)break即可
- switch也支持Character、String類(lèi)型
- Case 后面的條件也支持元組,區(qū)間,復(fù)合條件,值綁定
- public func print(_ items: Any..., separator: String = " ", terminator: String = "\n")
inout
- 可以用inout定義一個(gè)輸入輸出參數(shù):可以在函數(shù)內(nèi)部修改外部實(shí)參的值,func swapValues(_ v1: inout Int, _ v2: inout Int) {}
函數(shù)重載
- 函數(shù) 個(gè)數(shù) 標(biāo)簽 類(lèi)型不同(返回值類(lèi)型不同不叫重載)
- 默認(rèn)參數(shù)與函數(shù)重載一起用產(chǎn)生歧義的時(shí)候不報(bào)錯(cuò)(C++ 報(bào)錯(cuò))
高階函數(shù),返回值是函數(shù)類(lèi)型的是高階函數(shù)
- 每一個(gè)函數(shù)都是有類(lèi)型的,函數(shù)類(lèi)型由形式參數(shù)類(lèi)型、返回值類(lèi)型組成
- 函數(shù)類(lèi)型作為函數(shù)的返回值,
- 函數(shù)類(lèi)型作為函數(shù)參數(shù)
- 將一個(gè)接受多參數(shù)的函數(shù)變換為一系列只接受單個(gè)參數(shù)的函數(shù),叫做柯里化
-
像Array這樣支持map運(yùn)算的類(lèi)型,稱為函子(Functor)
截屏2021-10-21 下午3.36.41.png

內(nèi)斂函數(shù)
- 如果開(kāi)啟了編譯器優(yōu)化(Release模式默認(rèn)會(huì)開(kāi)啟優(yōu)化),編譯器會(huì)自動(dòng)將某些函數(shù)變成內(nèi)聯(lián)函數(shù)
- 將函數(shù)調(diào)用展開(kāi)成函數(shù)體
- 有些函數(shù)不被自動(dòng)內(nèi)斂(函數(shù)體較長(zhǎng),包含遞歸)
- 永遠(yuǎn)不會(huì)被內(nèi)聯(lián)(即使開(kāi)啟了編譯器優(yōu)化) @inline(never) func test() {}
- 被內(nèi)聯(lián)(開(kāi)啟了編譯器優(yōu)化即使過(guò)長(zhǎng)也被內(nèi)斂) @inline(__always) func test() {}
typealias
typealias用來(lái)給類(lèi)型起別名
枚舉
枚舉有擴(kuò)展
-
關(guān)聯(lián)值 將枚舉的成員值跟其他類(lèi)型的值關(guān)聯(lián)存儲(chǔ)在一起
截屏2021-10-21 下午5.15.30.png 原始值 注意:原始值不占用枚舉變量的內(nèi)存,隱式原始值如果枚舉的原始值類(lèi)型是Int、String,Swift會(huì)自動(dòng)分配原始值,int默認(rèn)0,1,String就是同名稱的字符串
空合并運(yùn)算符 ??
- a ?? b
- a 是可選項(xiàng) ,b 是可選項(xiàng) 或者 不是可選項(xiàng)
- b 跟 a 的存儲(chǔ)類(lèi)型必須相同
- 如果 a 不為nil,就返回 a
- 如果 a 為nil,就返回 b
- 如果 b 不是可選項(xiàng),返回 a 時(shí)會(huì)自動(dòng)解包
結(jié)構(gòu)體&類(lèi)
- 結(jié)構(gòu)體,編譯器會(huì)自動(dòng)生成可以傳入成員值的初始化方法,如果在定義結(jié)構(gòu)體的時(shí)候自定義了初始化方法,那么編譯器不會(huì)自動(dòng)生成;
- 類(lèi),編譯器不會(huì)自動(dòng)生成以傳入成員值的初始化方法,如果定義類(lèi)的時(shí)候,所有成員變量定義了初始值,那么編譯器會(huì)自動(dòng)生成無(wú)參的初始化方法
- 結(jié)構(gòu)體是值類(lèi)型(枚舉也是值類(lèi)型),類(lèi)是引用類(lèi)型(指針類(lèi)型)
結(jié)構(gòu)體定義的成員變量的值 - 類(lèi)是指針引用,棧上的指針引用堆上的實(shí)例對(duì)象;結(jié)構(gòu)體是值引用(值拷貝),實(shí)例內(nèi)存就在棧上
屬性
-
存儲(chǔ)屬性 :存儲(chǔ)在實(shí)例的內(nèi)存中,結(jié)構(gòu)體和類(lèi)可以定義存儲(chǔ)屬性,
- 存儲(chǔ)實(shí)例屬性:可以通過(guò)實(shí)例訪問(wèn),存儲(chǔ)在每個(gè)實(shí)例的內(nèi)存中
- 存儲(chǔ)類(lèi)型屬性:通過(guò)類(lèi)型訪問(wèn),整個(gè)程序運(yùn)行過(guò)程只分配一塊內(nèi)存
-
計(jì)算屬性(類(lèi)似于函數(shù),有g(shù)et set 方法,不占用實(shí)例內(nèi)存,結(jié)構(gòu)體和類(lèi)枚舉可以定義計(jì)算屬性)
- 計(jì)算實(shí)例屬性:可以通過(guò)實(shí)例訪問(wèn),存儲(chǔ)在每個(gè)實(shí)例的內(nèi)存中
-
計(jì)算類(lèi)型屬性:通過(guò)類(lèi)型訪問(wèn),只分配一塊內(nèi)存
截屏2021-10-23 下午11.47.39.png
inout的本質(zhì)就是引用傳遞(地址傳遞)
動(dòng)態(tài)類(lèi)型語(yǔ)言
- 運(yùn)行時(shí)才做數(shù)據(jù)類(lèi)型檢查,在編譯階段不給變量設(shè)置任何數(shù)據(jù)類(lèi)型,在第一次給變量賦值的時(shí)候,內(nèi)部會(huì)記錄下數(shù)據(jù)類(lèi)型
靜態(tài)類(lèi)型語(yǔ)言
- 編譯時(shí)就開(kāi)始做數(shù)據(jù)類(lèi)型檢查,變量聲明的就得設(shè)置數(shù)據(jù)類(lèi)型,使用之前也得聲明數(shù)據(jù)類(lèi)型
mutating
- 結(jié)構(gòu)體和枚舉是值類(lèi)型,默認(rèn)情況下,值類(lèi)型的屬性不能被自身的實(shí)例方法修改
- 在func關(guān)鍵字前加mutating可以允許這種修改行為
下標(biāo)(subscript)
n 使用subscript可以給任意類(lèi)型(枚舉、結(jié)構(gòu)體、類(lèi))增加下標(biāo)功能,有些地方也翻譯為:下標(biāo)腳本,本質(zhì)是方法,可以沒(méi)有set方法,必須要get方法
繼承
- 值類(lèi)型(枚舉、結(jié)構(gòu)體)不支持繼承,只有類(lèi)支持繼承
- 子類(lèi)可以重寫(xiě)父類(lèi)的下標(biāo)、方法、屬性,重寫(xiě)必須加上override關(guān)鍵字
- 被class修飾的類(lèi)型方法、下標(biāo),計(jì)算類(lèi)型屬性,允許被子類(lèi)重寫(xiě)
- 被static修飾的類(lèi)型方法、下標(biāo),類(lèi)型屬性,不允許被子類(lèi)重寫(xiě)
- 子類(lèi)可以將父類(lèi)的屬性(存儲(chǔ)、計(jì)算)重寫(xiě)為計(jì)算屬性
- 子類(lèi)不可以將父類(lèi)屬性重寫(xiě)為存儲(chǔ)屬性
- 只能重寫(xiě)var屬性,不能重寫(xiě)let屬性
- 子類(lèi)重寫(xiě)后的屬性權(quán)限 不能小于 父類(lèi)屬性的權(quán)限
- 被final修飾的方法、下標(biāo)、屬性,禁止被重寫(xiě)
- 被final修飾的類(lèi),禁止被繼承
Any、AnyObject
- Any:可以代表任意類(lèi)型(枚舉、結(jié)構(gòu)體、類(lèi),也包括函數(shù)類(lèi)型)
- pAnyObject:可以代表任意類(lèi)類(lèi)型(在協(xié)議后面寫(xiě)上: AnyObject代表只有類(lèi)能遵守這個(gè)協(xié)議),在協(xié)議后面寫(xiě)上: class也代表只有類(lèi)能遵守這個(gè)協(xié)議
錯(cuò)誤類(lèi)型
- Swift中可以通過(guò)Error協(xié)議自定義運(yùn)行時(shí)的錯(cuò)誤信息
- 函數(shù)內(nèi)部可以通過(guò)throw 拋出自定義errow
- 可以使用do-catch捕捉Error
- defer語(yǔ)句:用來(lái)定義以任何方式(拋錯(cuò)誤、return等)離開(kāi)代碼塊前必須要執(zhí)行的代碼
- defer語(yǔ)句將延遲至當(dāng)前作用域結(jié)束之前執(zhí)行
- defer語(yǔ)句將延遲至當(dāng)前作用域結(jié)束之前執(zhí)行
- assert(斷言)
- 如果遇到嚴(yán)重問(wèn)題,希望結(jié)束程序運(yùn)行時(shí),可以直接使用fatalError函數(shù)拋出錯(cuò)誤(這是無(wú)法通過(guò)do-catch捕捉的錯(cuò)誤)
- 使用了fatalError函數(shù),就不需要再寫(xiě)return, 在某些不得不實(shí)現(xiàn)、但不希望別人調(diào)用的方法,可以考慮內(nèi)部使用fatalError函數(shù)
- 可以使用do 實(shí)現(xiàn)局部作用域
閉包&自動(dòng)閉包

- 如果將一個(gè)很長(zhǎng)的閉包表達(dá)式作為函數(shù)的最后一個(gè)實(shí)參,使用尾隨閉包可以增強(qiáng)函數(shù)的可讀性
- 尾隨閉包是一個(gè)被書(shū)寫(xiě)在函數(shù)調(diào)用括號(hào)(后面)的閉包表達(dá)式
逃逸閉包
- 逃逸閉包: 閉包作為函數(shù)的參數(shù)傳遞時(shí),在函數(shù)體結(jié)束之后調(diào)用,就說(shuō)閉包逃避了函數(shù)的作用域,這個(gè)閉包是逃逸型的閉包,使用@escaping來(lái)標(biāo)注, 逃逸閉包一般會(huì)在多線程中使用
- 非逃逸型的閉包:在函數(shù)體結(jié)束前被調(diào)用,閉包是非逃逸型的閉包。
協(xié)議
- 只有將協(xié)議中的實(shí)例方法標(biāo)記為mutating,才允許結(jié)構(gòu)體、枚舉的具體實(shí)現(xiàn)修改自身成員變量
- 類(lèi)在實(shí)現(xiàn)方法時(shí)不用加mutating,枚舉、結(jié)構(gòu)體才需要加mutating
- 協(xié)議中還可以定義初始化器init ,非final類(lèi)實(shí)現(xiàn)時(shí)必須加上required
- 如果從協(xié)議實(shí)現(xiàn)的初始化器,剛好是重寫(xiě)了父類(lèi)的指定初始化器 ,那么實(shí)現(xiàn)的時(shí)候這個(gè)初始化必須同時(shí)加required override
- 一個(gè)協(xié)議可以繼承其他協(xié)議
- 枚舉,類(lèi),類(lèi)都可以遵守協(xié)議
- 協(xié)議可以添加擴(kuò)展
- 協(xié)議擴(kuò)展可以為遵守協(xié)議的類(lèi)型添加實(shí)現(xiàn),但它不能使協(xié)議從另一個(gè)協(xié)議擴(kuò)展或繼承。協(xié)議繼承始終在協(xié)議聲明本身指定。
- 如果一個(gè)類(lèi)型已經(jīng)符合協(xié)議的所有要求,但是還未聲明采用了該協(xié)議,則可以讓它采用一個(gè)空擴(kuò)展的協(xié)議:
- is用來(lái)判斷是否為某種類(lèi)型,as用來(lái)做強(qiáng)制類(lèi)型轉(zhuǎn)換
- 枚舉結(jié)構(gòu)體協(xié)議類(lèi)都可以加擴(kuò)展


