前言:
最近把 iOS 面試中可能會遇到的問題整理了一番, 題目大部分是網(wǎng)上收錄的, 方便自己鞏固復(fù)習(xí), 也分享給大家; 希望對大家有所幫助!
一、OC部分
1.什么是runtime?
1.runtime 運(yùn)行時(shí)機(jī)制,是一套比較底層的純 C 語言 API , 屬于1個(gè) C 語言庫, 包含了很多底層的 C 語言 API 。(引入 <objc/runtime.h> 或者 <objc/message.h> )
2.程序運(yùn)行過程時(shí),我們平時(shí)編寫的 OC 代碼, 其實(shí)最終都是轉(zhuǎn)成了 runtime 的 C 語言代碼。
3.在編譯的時(shí)候并不能決定真正調(diào)用哪個(gè)函數(shù),只有在真正運(yùn)行的時(shí)候才能根據(jù)函數(shù)的名稱找到對應(yīng)的函數(shù)來調(diào)用。
2.runtime 是干什么用的?使用場景是什么?
1.OC的動(dòng)態(tài)性就是由Runtime來支撐和實(shí)現(xiàn)的,Runtime是一套C語言的API,封裝了很多動(dòng)態(tài)性相關(guān)的函數(shù)
2.利用關(guān)聯(lián)對象(AssociatedObject)給分類添加屬性
3.遍歷類的所有成員變量(修改textfield的占位文字顏色、字典轉(zhuǎn)模型、自動(dòng)歸檔解檔)
4.利用消息轉(zhuǎn)發(fā)機(jī)制解決方法找不到的異常問題
5.KVC、KVO都是基于runtime實(shí)現(xiàn)的。
3.講一下 OC 的消息機(jī)制
1.當(dāng)向一個(gè)對象發(fā)送消息時(shí),objc_msgSend 方法根據(jù)對象的 isa 指針找到對象的類,然后在類的調(diào)度表(dispatch table)中查找 selector。
2.如果無法找到 selector,objc_msgSend 通過指向父類的指針找到父類,并在父類的調(diào)度表(dispatch table)中查找 selector,以此類推直到 NSObject 類。
3.一旦查找到 selector,objc_msgSend 方法根據(jù)調(diào)度表的內(nèi)存地址調(diào)用該實(shí)現(xiàn)。
4.通過這種方式,message 與方法的真正實(shí)現(xiàn)才在執(zhí)行階段進(jìn)行綁定。
5.為了保證消息發(fā)送與執(zhí)行的效率,系統(tǒng)會將全部 selector 和使用過的方法的內(nèi)存地址緩存起來。
6.每個(gè)類都有一個(gè)獨(dú)立的緩存,緩存包含有當(dāng)前類自己的 selector 以及繼承自父類的 selector。
7.查找調(diào)度表(dispatch table)前,消息發(fā)送系統(tǒng)首先檢查 receiver 對象的緩存;緩存命中的情況下,消息發(fā)送(messaging)比直接調(diào)用方法(function call)只慢一點(diǎn)點(diǎn)。
4.動(dòng)態(tài)綁定
1,在運(yùn)行時(shí)確定要調(diào)用的方法,動(dòng)態(tài)綁定將調(diào)用方法的確定也推遲到運(yùn)行時(shí)。
2.在編譯時(shí),方法的調(diào)用并不和代碼綁定在一起,只有在消實(shí)發(fā)送出來之后,才確定被調(diào)用的代碼。
3.通過動(dòng)態(tài)類型和動(dòng)態(tài)綁定技術(shù),您的代碼每次執(zhí)行都可以得到不同的結(jié)果。
4.運(yùn)行時(shí)負(fù)責(zé)確定消息的接收者和被調(diào)用的方法;運(yùn)行時(shí)的消息分發(fā)機(jī)制為動(dòng)態(tài)綁定提供支持。
5.當(dāng)您向一個(gè)動(dòng)態(tài)類型確定了的對象發(fā)送消息時(shí),運(yùn)行環(huán)境系統(tǒng)會通過接收者的 isa 指針定位對象的類,并以此為起點(diǎn)確定被調(diào)用的方法,方法和消息是動(dòng)態(tài)綁定的。而且,您不必在 Objective-C 代碼中做任何工作,就可以自動(dòng)獲取動(dòng)態(tài)綁定的好處。
6.您在每次發(fā)送消息時(shí),特別是當(dāng)消息的接收者是動(dòng)態(tài)類型已經(jīng)確定的對象時(shí),動(dòng)態(tài)綁定就會例行而透明地發(fā)生。
5.講一下isa指針
1.isa 等價(jià)于 is kind of
實(shí)例對象 isa 指向類對象
類對象 isa 指向元類對象
元類對象的 isa 指向元類的基類
6.iOS中實(shí)現(xiàn)多線程的幾種方案,各自有什么特點(diǎn)?
1.NSThread 面向?qū)ο蟮模枰绦騿T手動(dòng)創(chuàng)建線程,但不需要手動(dòng)銷毀。子線程間通信很難。
2.GCD c語言,充分利用了設(shè)備的多核,自動(dòng)管理線程生命周期。比NSOperation效率更高。
3.NSOperation 基于gcd封裝,更加面向?qū)ο螅萭cd多了一些功能。
7.GCD執(zhí)行原理?
1.GCD有一個(gè)底層線程池,這個(gè)池中存放的是一個(gè)個(gè)的線程。之所以稱為“池”,很容易理解出這個(gè)“池”中的線程是可以重用的,當(dāng)一段時(shí)間后這個(gè)線程沒有被調(diào)用胡話,這個(gè)線程就會被銷毀。注意:開多少條線程是由底層線程池決定的(線程建議控制再3~5條),池是系統(tǒng)自動(dòng)來維護(hù),不需要我們程序員來維護(hù)(看到這句話是不是很開心?) 而我們程序員需要關(guān)心的是什么呢?我們只關(guān)心的是向隊(duì)列中添加任務(wù),隊(duì)列調(diào)度即可。
2.如果隊(duì)列中存放的是同步任務(wù),則任務(wù)出隊(duì)后,底層線程池中會提供一條線程供這個(gè)任務(wù)執(zhí)行,任務(wù)執(zhí)行完畢后這條線程再回到線程池。這樣隊(duì)列中的任務(wù)反復(fù)調(diào)度,因?yàn)槭峭降模援?dāng)我們用currentThread打印的時(shí)候,就是同一條線程。
如果隊(duì)列中存放的是異步的任務(wù),(注意異步可以開線程),當(dāng)任務(wù)出隊(duì)后,底層線程池會提供一個(gè)線程供任務(wù)執(zhí)行,因?yàn)槭钱惒綀?zhí)行,隊(duì)列中的任務(wù)不需等待當(dāng)前任務(wù)執(zhí)行完畢就可以調(diào)度下一個(gè)任務(wù),這時(shí)底層線程池中會再次提供一個(gè)線程供第二個(gè)任務(wù)執(zhí)行,執(zhí)行完畢后再回到底層線程池中。
3.這樣就對線程完成一個(gè)復(fù)用,而不需要每一個(gè)任務(wù)執(zhí)行都開啟新的線程,也就從而節(jié)約的系統(tǒng)的開銷,提高了效率。在iOS7.0的時(shí)候,使用GCD系統(tǒng)通常只能開58條線程,iOS8.0以后,系統(tǒng)可以開啟很多條線程,但是實(shí)在開發(fā)應(yīng)用中,建議開啟線程條數(shù):35條最為合理。
8.多個(gè)網(wǎng)絡(luò)請求完成后執(zhí)行下一步
1.使用GCD的dispatch_group_t
每次網(wǎng)絡(luò)請求前先dispatch_group_enter(進(jìn)入),請求回調(diào)后再dispatch_group_leave(離開),enter和leave必須配合使用,有幾次enter就要有幾次leave,否則group會一直存在。
當(dāng)所有enter的block都leave后,會執(zhí)行dispatch_group_notify的block。
2.使用GCD的信號量dispatch_semaphore_t
9.異步操作兩組數(shù)據(jù)時(shí), 執(zhí)行完第一組之后, 才能執(zhí)行第二組
這里使用dispatch_barrier_async柵欄方法即可實(shí)現(xiàn)
10.什么情況使用 weak 關(guān)鍵字,相比 assign 有 什么不同?
1.在 ARC 中,在有可能出現(xiàn)循環(huán)引用的時(shí)候,往往要通過讓其中一端使用 weak 來解決, 比如:delegate 代理屬性, 自身已經(jīng)對它進(jìn)行一次強(qiáng)引用,沒有必要再強(qiáng)引用一次,此時(shí)也會使用 weak,自定義 IBOutlet 控件屬性一般也使用 weak;當(dāng)然,也可以使用 strong,但是建議使用 weak
2.weak 策略在屬性所指的對象遭到摧毀時(shí),系統(tǒng)會將 weak 修飾的屬性對象的指針指 向 nil,在 OC 給 nil 發(fā)消息是不會有什么問題的; 如果使用 assign 策略在屬性所指 的對象遭到摧毀時(shí),屬性對象指針還指向原來的對象,由于對象已經(jīng)被銷毀,這時(shí)候就產(chǎn)生了野指針,如果這時(shí)候在給此對象發(fā)送消息,很容造成程序奔潰 assigin 可以用于修飾非 OC 對象,而 weak 必須用于 OC 對象
11.怎么用 copy 關(guān)鍵字?
1.NSString、NSArray、NSDictionary 等等經(jīng)常使用 copy 關(guān)鍵字,是因?yàn)樗麄冇袑?yīng) 的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,為確保 對象中的屬性值不會無意間變動(dòng),應(yīng)該在設(shè)置新屬性值時(shí)拷貝一份,保護(hù)其封裝性
2.block 也經(jīng)常使用 copy 關(guān)鍵字,方法內(nèi)部的 block 默認(rèn)是 在棧區(qū)的,使用 copy 可以把它放到堆區(qū).
12.怎么樣優(yōu)化APP啟動(dòng)速度?
1.在main函數(shù)執(zhí)行之前
1.1盡量刪除一些不必要的系統(tǒng)文件和第三方庫。
1.2盡量刪除一些不必要的.h .m 文件。
1.3盡量不要在類的load函數(shù)放入大量初始化信息,這樣會延遲加載時(shí)間。
2.didfinishlauch函數(shù)到第一個(gè)主界面加載顯示階段
2.1減少不必要的網(wǎng)絡(luò)請求。
2.2較少不必要的數(shù)據(jù)初始化操作,盡量寫成懶加載
2.3減少一些第三方sdk的初始化和版本檢測相關(guān)代碼
13.UIView 和 CALayer 的區(qū)別?
UIView 是 CALayer 的 delegate,UIView 可以響應(yīng)事件,而 CA Layer 則不能。
14.KVC 的主要應(yīng)用的場景與注意的事項(xiàng)
KVC全稱(key-Value coding)稱呼為鍵值編碼,在iOS開發(fā)中。允許開發(fā)者通過key名直接訪問對象的屬性,或者給對象的屬性賦值。需要調(diào)用明確的存取方法,這樣就可以在運(yùn)行時(shí)動(dòng)態(tài)訪問和修改對象的屬性,而不是在編譯時(shí)確定。
15.iOS類別的作用?繼承和類別在實(shí)現(xiàn)中有何區(qū)別?
category 可以在不獲悉,不改變原來代碼的情況下往里面添加新的方法,只能添加,不能刪除修改。 并且如果類別和原來類中的方法產(chǎn)生名稱沖突,則類別將覆蓋原來的方法,因?yàn)轭悇e具有更高的優(yōu)先級。
類別主要有3個(gè)作用:
(1)將類的實(shí)現(xiàn)分散到多個(gè)不同文件或多個(gè)不同框架中。
(2)創(chuàng)建對私有方法的前向引用。
(3)向?qū)ο筇砑臃钦絽f(xié)議。 繼承可以增加,修改或者刪除方法,并且可以增加屬性。
生效周期:Category是runtime,Extension是編譯時(shí)。
Category可以為系統(tǒng)類添加分類,Extension不能。
文件:Category是有h聲明和m實(shí)現(xiàn),Extension直接寫在宿主.m文件,只有h聲明。
Category只能擴(kuò)充方法,不能擴(kuò)充成員變量和屬性,因?yàn)槌蓡T變量是編譯時(shí)的,屬性會在編譯時(shí)自動(dòng)生成setter和getter,但Category是runtime。
16.KVO是什么?簡述KVO的實(shí)現(xiàn)原理。KVO是否能監(jiān)聽數(shù)組?如何實(shí)現(xiàn)?
KVO(鍵值觀察):它可以使對象獲取其他對象屬性變化的通知機(jī)制。
調(diào)用KVC會觸發(fā)KVO。
KVO使用了isa-swizzling方式結(jié)合RunTime動(dòng)態(tài)性,在給對象首次添加KVO時(shí),RunTime會動(dòng)態(tài)創(chuàng)建被監(jiān)聽對象的子類(NSKVONofifying_ClassName),然后實(shí)現(xiàn)setter,class,dealloc,_isKVOA方法,并在setter方法中實(shí)現(xiàn)對應(yīng)通知機(jī)制。接下來將被監(jiān)聽對象isa指向動(dòng)態(tài)創(chuàng)建的子類。使用KVC修改屬性值時(shí),會調(diào)用動(dòng)態(tài)創(chuàng)建的子類中對應(yīng)setter方法,觸發(fā)通知機(jī)制,如此便實(shí)現(xiàn)了KVO。
KVO監(jiān)聽數(shù)組需實(shí)現(xiàn) NSMutableArray 的增刪改操作遵從 KVC 的規(guī)則:
增: -insertObject:inAtIndex: 或者 -insert:atIndexes:
刪: -removeObjectFromAtIndex: 或者 -removeAtIndexes:
改:-replaceObjectInAtIndex:withObject: 或者 -replaceAtIndexes:with:
并將這些接口暴露給調(diào)用者,在對數(shù)組進(jìn)行操作時(shí)需使用上述實(shí)現(xiàn)的接口。
16.如何理解RunLoop
在主線程中默認(rèn)開啟RunLoop,它不斷地監(jiān)聽系統(tǒng)事件,如觸摸事件、定時(shí)器事件等,一旦有事件發(fā)生,就會通知相應(yīng)的處理方法來處理該事件。
Swift相關(guān):
1.類(class)和 結(jié)構(gòu)體(struct)有什么區(qū)別?
Struct不支持繼承,Class支持繼承
Struct是值類型,Class是引用類型
Struct使用let創(chuàng)建不可變,Class使用let創(chuàng)建可變
Struct無法修改自身屬性值,函數(shù)需要添加mutating關(guān)鍵字
Struct不需要deinit方法,因?yàn)橹殿愋筒魂P(guān)系引用計(jì)數(shù),Class需要deinit方法
Struct初始化方法是基于屬性的
2.map、filter、reduce 的作用
map 用于映射, 可以將一個(gè)列表轉(zhuǎn)換為另一個(gè)列表
filter 用于過濾, 可以篩選出想要的元素
reduce 合并
3.String 與 NSString 的關(guān)系與區(qū)別
NSString 與 String 之間可以隨意轉(zhuǎn)換,
String 是結(jié)構(gòu)體, 值類型, NSString 是類, 引用類型.
通常, 沒必要使用 NSString 類, 除非你要使用一些特有方法, 例如使用 pathExtension 屬性
4.什么是高階函數(shù)
一個(gè)函數(shù)如果可以以某一個(gè)函數(shù)作為參數(shù), 或者是返回值, 那么這個(gè)函數(shù)就稱之為高階函數(shù), 如 map, reduce, filter
5.逃逸閉包,非逃逸閉包,尾隨閉包
1.非逃逸閉包:一個(gè)接受閉包作為參數(shù)的函數(shù),閉包是在這個(gè)函數(shù)結(jié)束前內(nèi)被調(diào)用,即可以理解為閉包是在函數(shù)作用域結(jié)束前被調(diào)用
1、不會產(chǎn)生循環(huán)引用,因?yàn)殚]包的作用域在函數(shù)作用域內(nèi),在函數(shù)執(zhí)行完成后,就會釋放閉包捕獲的所有對象
2、針對非逃逸閉包,編譯器會做優(yōu)化:省略內(nèi)存管理調(diào)用
2.逃逸閉包:一個(gè)接受閉包作為參數(shù)的函數(shù),逃逸閉包可能會在函數(shù)返回之后才被調(diào)用,即閉包逃離了函數(shù)的作用域
1、可能會產(chǎn)生循環(huán)引用,因?yàn)樘右蓍]包中需要顯式的引用self(猜測其原因是為了提醒開發(fā)者,這里可能會出現(xiàn)循環(huán)引用了),而self可能是持有閉包變量的(與OC中block的的循環(huán)引用類似)
2、一般用于異步函數(shù)的返回,例如網(wǎng)絡(luò)請求
3.尾隨閉包:函數(shù)的最后一個(gè)參數(shù)是閉包,就叫做尾隨閉包,可以增強(qiáng)可讀性
6.Swift比Objective-C有什么優(yōu)勢?
1、Swift是強(qiáng)類型(靜態(tài))語言,有類型推斷,Objective-C弱類型(動(dòng)態(tài))語言
2、Swift面向協(xié)議編程,Objective-C面向?qū)ο缶幊?br>
3、Swift注重值類型,Objective-C注重引用類型
4、Swift支持泛型,Objective-C只支持輕量泛型(給集合添加泛型)
5、Swift支持靜態(tài)派發(fā)(效率高)、動(dòng)態(tài)派發(fā)(函數(shù)表派發(fā)、消息派發(fā))方式,Objective-6、C支持動(dòng)態(tài)派發(fā)(消息派發(fā))方式
7、Swift支持函數(shù)式編程(高階函數(shù))
8、Swift的協(xié)議不僅可以被類實(shí)現(xiàn),也可以被Struct和Enum實(shí)現(xiàn)
9、Swift有元組類型、支持運(yùn)算符重載
10、Swift支持命名空間
11、Swift支持默認(rèn)參數(shù)
12、Swift比Objective-C代碼更簡潔
7.Swift的可選項(xiàng)類型(Optionals)介紹
Swift引入了可選項(xiàng)類型,用于處理變量值不存在的情況。Optionals類似于OC中指向nil的指針,但是適用于所有數(shù)據(jù)類型,而非僅僅局限于類,Optionals相比于OC中的nil指針,更加安全和簡明,并且也是Swift諸多最強(qiáng)大功能的核心。
8.Swift中的 !和 ?
這兩個(gè)符號是用來標(biāo)記這個(gè)變量的值是否可選,!表示可選變量必須保證轉(zhuǎn)換能夠成功,否則報(bào)錯(cuò),但定義的變量可以直接使用;?表示可選變量即使轉(zhuǎn)換不成功也不會報(bào)錯(cuò),變量值為nil,如果轉(zhuǎn)換成功,要使用該變量時(shí),后面需要加!進(jìn)行修飾。
9.講講Swift的派發(fā)機(jī)制
函數(shù)的派發(fā)機(jī)制:靜態(tài)派發(fā)(直接派發(fā))、函數(shù)表派發(fā)、消息派發(fā)
swift派發(fā)機(jī)制總結(jié):
Swift中所有ValueType(值類型:Struct、Enum)使用直接派發(fā);
Swift中協(xié)議的Extensions使用直接派發(fā),初始聲明函數(shù)使用函數(shù)表派發(fā);
Swift中Class中Extensions使用直接派發(fā),初始聲明函數(shù)使用函數(shù)表派發(fā),dynamic修飾的函數(shù)使用消息派發(fā);
Swift中NSObject的子類用@nonobjc或final修飾的函數(shù)使用直接派發(fā),初始聲明函數(shù)使用函數(shù)表派發(fā),dynamic修飾的Extensions使用消息派發(fā);
3)Swift中函數(shù)派發(fā)查看方式: 可將Swift代碼轉(zhuǎn)換為SIL(中間碼)
swiftc -emit-silgen -O example.swift
10.什么是泛型?泛型是用來解決什么問題的?
泛型是用來使類型和算法安全的工作的一種類型。在 Swift 中,在函數(shù)和數(shù)據(jù)結(jié)構(gòu)中都可以使用泛型,例如類、結(jié)構(gòu)體和枚舉。
泛型一般是用來解決代碼復(fù)用的問題。常見的一種情況是,你有一個(gè)函數(shù),它帶有一個(gè)參數(shù),參數(shù)類型是 A,然而當(dāng)參數(shù)類型改變成B的時(shí)候,你不得不復(fù)制這個(gè)函數(shù)。
11.Swift常用關(guān)鍵字
1、class
在Swift當(dāng)中, 我們使用Class關(guān)鍵字去聲明一個(gè)類和聲明類方法
2、let
Swift里用let修飾的變量會是一個(gè)不可變的常量,即我們不可以對它進(jìn)行修改
3、var
Swift中用var修飾的變量是一個(gè)可變的變量,即可以對它進(jìn)行修改
4、struct
在Swift中, 我們使用struct關(guān)鍵字去聲明結(jié)構(gòu)體
5、enum
在Swift中, 我們使用enum關(guān)鍵字去聲明枚舉
6、final
Swift中,final關(guān)鍵字可以在class、func和var前修飾。表示 不可重寫 可以將類或者類中的部分實(shí)現(xiàn)保護(hù)起來,從而避免子類破壞
7、override
在Swift中, 如果我們要重寫某個(gè)方法, 或者某個(gè)屬性的話, 我們需要在重寫的變量前增加一個(gè)override關(guān)鍵字
8、subscript
在Swft中,subscript關(guān)鍵字表示下標(biāo),可以讓class、struct、以及enum使用下標(biāo)訪問內(nèi)部的值
9、static
Swift中,用static關(guān)鍵字聲明靜態(tài)變量或者函數(shù),它保證在對應(yīng)的作用域當(dāng)中只有一份, 同時(shí)也不需要依賴實(shí)例化
10、mutating
Swift中,mutating關(guān)鍵字指的是可變即可修改。用在structure和enumeration中,雖然結(jié)構(gòu)體和枚舉可以定義自己的方法,但是默認(rèn)情況下,實(shí)例方法中是不可以修改值類型的屬性。為了能夠在實(shí)例方法中修改屬性值,可以在方法定義前添加關(guān)鍵字mutating
11、typealias
在Swift中,使用關(guān)鍵字typealias定義類型別名(typealias就相當(dāng)于objective-c中的typedef),就是將類型重命名,看起來更加語義化
12、lazy
在Swift中,lazy關(guān)鍵修飾的變量, 只有在第一次被調(diào)用的時(shí)候才會去初始化值(即懶加載)
13、init
在Swift 中,init關(guān)鍵字也表示構(gòu)造器
14、required
在Swift里,required是用來修飾init方法的,說明該構(gòu)造方法是必須實(shí)現(xiàn)的
15、extension
在swift中,extension與Objective-C的category有點(diǎn)類似,但是extension比起category來說更加強(qiáng)大和靈活,它不僅可以擴(kuò)展某種類型或結(jié)構(gòu)體的方法,同時(shí)它還可以與protocol等結(jié)合使用,編寫出更加靈活和強(qiáng)大的代碼。它可以為特定的class, strut, enum或者protocol添加新的特性。當(dāng)你沒有權(quán)限對源代碼進(jìn)行改造的時(shí)候,此時(shí)可以通過extension來對類型進(jìn)行擴(kuò)展
16、convenient
swift中,使用convenience修飾的構(gòu)造函數(shù)叫做便利構(gòu)造函數(shù) 。便利構(gòu)造函數(shù)通常用在對系統(tǒng)的類進(jìn)行構(gòu)造函數(shù)的擴(kuò)充時(shí)使用
17、deinit
在Swift中,deinit屬于析構(gòu)函數(shù),當(dāng)對象結(jié)束其生命周期時(shí)(例如對象所在的函數(shù)已調(diào)用完畢),系統(tǒng)自動(dòng)執(zhí)行析構(gòu)函數(shù)。和OC中的dealloc 一樣的
18、fallthrough
swift語言特性switch語句的break可以忽略不寫,滿足條件時(shí)直接跳出循環(huán).fallthrough的作用就是執(zhí)行完當(dāng)前case,繼續(xù)執(zhí)行下面的case.類似于其它語言中省去break里,會繼續(xù)往后一個(gè)case跑,直到碰到break或default才完成的效果
19、protocol
在Swift中,protocol關(guān)鍵字也是屬于協(xié)議
20、open
在Swift中,open修飾的對象表示可以被任何人使用,包括override和繼承
21、public
在Swift中,public表示公有訪問權(quán)限,類或者類的公有屬性或者公有方法可以從文件或者模塊的任何地方進(jìn)行訪問
22、internal
在Swift中,public表示內(nèi)部的訪問權(quán)限。即有著internal訪問權(quán)限的屬性和方法說明在模塊內(nèi)部可以訪問,超出模塊內(nèi)部就不可被訪問了。在Swift中默認(rèn)就是internal的訪問權(quán)限。
23、private
在Swift中,private私有訪問權(quán)限。被private修飾的類或者類的屬性或方法可以在同一個(gè)物理文件中訪問。如果超出該物理文件,那么有著private訪問權(quán)限的屬性和方法就不能被訪問
24、fileprivate
在Swift中,fileprivate訪問級別所修飾的屬性或者方法在當(dāng)前的Swift源文件里可以訪問
說明:5種修飾符訪問權(quán)限排序open> public > interal > fileprivate > private。
12.指定構(gòu)造器和便利構(gòu)造器有什么區(qū)別?
類必須要有一個(gè)指定構(gòu)造器,可以沒有便利構(gòu)造器
便利構(gòu)造器必須調(diào)用本類另一個(gè)構(gòu)造器,最終調(diào)用到本類的指定構(gòu)造器
便利構(gòu)造器前面需要添加convenience關(guān)鍵字
13.Swift中的訪問控制權(quán)限?
Open:實(shí)體可被同一模塊內(nèi)所有實(shí)體訪問,模塊外可導(dǎo)入該模塊即可訪問,模塊外可被繼承和重寫。
Public:實(shí)體可被同一模塊內(nèi)所有實(shí)體訪問,模塊外可導(dǎo)入該模塊即可訪問,模塊外不能被繼承和重寫。
Internal:實(shí)體可被同一模塊內(nèi)所有實(shí)體訪問,模塊外無法訪問,大部分實(shí)體默認(rèn)是Internal級別。
fileprivate:限制實(shí)體只能在當(dāng)前文件內(nèi)訪問到,不管是否在本類的作用域。
private: 限制實(shí)體只能在本類的作用域且在當(dāng)前文件內(nèi)能訪問。
14.try try? try! 的區(qū)別
try 出現(xiàn)異常處理異常
try? 不處理異常,返回一個(gè)可選值類型,出現(xiàn)異常返回nil
try! 不讓異常繼續(xù)傳播,一旦出現(xiàn)異常程序停止,類似NSAssert()
15.計(jì)算屬性與存儲屬性
存儲屬性就是存儲在特定類、結(jié)構(gòu)體里的一個(gè)常量或者變量。
可以在定義存儲屬性的時(shí)候指定默認(rèn)值。
可以在構(gòu)造過程中設(shè)置或者修改存儲屬性的值。
枚舉、類、結(jié)構(gòu)體除了擁有存儲屬性,還可以定義計(jì)算屬性。
計(jì)算屬性不直接存儲值,而是提供一個(gè)getter和一個(gè)可選的setter來間接獲取、設(shè)置其他屬性和變量的值