iOS面試中經(jīng)常遇到的問題(二)

1、Runtime消息轉(zhuǎn)發(fā)機(jī)制?

1、Runtime是什么?

不嚴(yán)謹(jǐn)?shù)恼f法:
1、運(yùn)行時(shí)(Runtime)是指將數(shù)據(jù)類型的確定由編譯時(shí)推遲到了運(yùn)行時(shí)。
2、Runtime是一套比較底層的C語言API, 屬于1個(gè)C語言庫, 包含了很多底層的C語言API。
3、平時(shí)編寫的OC代碼,在程序運(yùn)行過程中,其實(shí)最終會轉(zhuǎn)換成Runtime的C語言代碼,Runtime是Object-C的幕后工作者。
4、Object-C需要Runtime來創(chuàng)建類和對象,進(jìn)行消息發(fā)送和轉(zhuǎn)發(fā)。
較嚴(yán)謹(jǐn)說法:
1、將盡可能多的決策從編譯時(shí)和鏈接時(shí)推遲到運(yùn)行時(shí)。
2、運(yùn)行時(shí)系統(tǒng)充當(dāng)著Object-C語言的操作系統(tǒng),它使語言能夠工作。
3、Runtime編寫的代碼具有運(yùn)行時(shí)、動態(tài)特性。

2、Runtime與OC的交互方式

1、通過Object-C源代碼進(jìn)行交互。
2、通過NSObject類中定義的方法交互。
3、通過直接調(diào)用運(yùn)行時(shí)函數(shù)。

3、Runtime的作用以及常見用法

Runtime的作用:
1、在程序運(yùn)行過程中,動態(tài)的創(chuàng)建類,動態(tài)添加、修改這個(gè)類的屬性和方法。
2、遍歷一個(gè)類中所有的成員變量、屬性、以及所有方法。
3、消息傳遞、轉(zhuǎn)發(fā)。
Runtime常見用法:
1、給系統(tǒng)分類添加屬性、方法。
2、方法交換。
3、獲取對象的屬性、私有屬性。
4、字典轉(zhuǎn)換模型。
5、KVC、KVO。
6、歸檔(編碼、解碼)。
7、獲取類名。
8、block。
...

4、Runtime定義

NSObject的定義:

@interface NSObject <NSObject> {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-interface-ivars"
    Class isa  OBJC_ISA_AVAILABILITY;
#pragma clang diagnostic pop
}

NSObject是一個(gè)Class類型來表示的指向objc_class結(jié)構(gòu)體的指針。

/// An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

/// Represents an instance of a class.
struct objc_object {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;
};
/// A pointer to an instance of a class.
typedef struct objc_object *id;

id和Class指向的都是objc_class結(jié)構(gòu)體
objc_class結(jié)構(gòu)體中的定義:

struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class _Nullable super_class                              OBJC2_UNAVAILABLE;
    const char * _Nonnull name                               OBJC2_UNAVAILABLE;
    long version                                             OBJC2_UNAVAILABLE;
    long info                                                OBJC2_UNAVAILABLE;
    long instance_size                                       OBJC2_UNAVAILABLE;
    struct objc_ivar_list * _Nullable ivars                  OBJC2_UNAVAILABLE;
    struct objc_method_list * _Nullable * _Nullable methodLists                    OBJC2_UNAVAILABLE;
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE;
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

4、Runtime消息機(jī)制

在OC中所有調(diào)用的方法,都是Runtime通過objc_msgSend向這個(gè)類發(fā)送消息。
Objc-msgSend消息傳遞的過程:
1、消息發(fā)送給對象時(shí),消息傳遞函數(shù)遵循對象的isa指針指向類結(jié)構(gòu)的指針,在該結(jié)構(gòu)中它查詢結(jié)構(gòu)體變量methodLists中的方法SEL(方法選擇器)。
2、如在isa指向的類結(jié)構(gòu)中找不到SEL(方法選擇器),Objc_msgSend會跟隨指向Supercalss(父類)指針并再次嘗試查找該SEL。
3、如連續(xù)失敗直到NSObject類,它的superclass也就是它自己本身。
4、一旦找到SEL,該函數(shù)就會調(diào)用methodLists的方法并將接收對象的指針傳給它。

消息的加速發(fā)送:

有的時(shí)候在一個(gè)類會有繼承關(guān)系,Objective-C中大部分對象都是繼承于NSObject、自己自定義類,在這種繼承體系當(dāng)中有很多的方法,這些方法有可能不會用到,在向類發(fā)送消息的時(shí)候,去methodLists中查找無疑會拖慢程序的運(yùn)行速度,所以Apple在開發(fā)的時(shí)候加入了cache的概念,也就是緩存。
在每個(gè)類中都會有一個(gè)單獨(dú)的緩存,它可以包含繼承過來的方法SEL以及自己定義的SEL,在搜索methodLists之前,消息傳遞程序會檢查接受者對象的告訴緩存cache,如果找到,就不會再去搜索methodLists列表。
cache緩存的是一些已經(jīng)調(diào)用過的SEL,當(dāng)寫的程序預(yù)熱足夠時(shí)間,那么所有發(fā)送過的SEL都會在cache中找到。
cache會動態(tài)增長,直到程序中所有調(diào)用的SEL運(yùn)行一遍為止。

5、Runtime消息轉(zhuǎn)發(fā)

消息的傳遞過程中,當(dāng)調(diào)用的對象的方法不存在時(shí),會觸發(fā)消息的轉(zhuǎn)發(fā)機(jī)制。
消息轉(zhuǎn)發(fā)過程:
1.動態(tài)方法解析

+(BOOL)resolveInstanceMethod:(SEL)sel 實(shí)例方法解析
+(BOOL)resolveClassMethod:(SEL)sel 類方法解析

當(dāng)運(yùn)用消息轉(zhuǎn)發(fā)運(yùn)行時(shí),根據(jù)調(diào)用的方法類型調(diào)用這兩個(gè)方法其中一個(gè),返回值BOOL類型,告訴系統(tǒng)該消息是否被處理,YES處理 NO 未處理。
當(dāng)這個(gè)對象在實(shí)現(xiàn)了resolveInstanceMethod,resolveClassMethod兩個(gè)方法,并沒有對該對象消息進(jìn)行處理,那么該方法會被調(diào)用兩次:
一次是沒有找到該方法需要對象解析處理;第二次是告訴系統(tǒng)我處理完成需要再次調(diào)用該方法但實(shí)際上并沒有處理完成,所以會調(diào)用第二次該方法崩潰。
2.后備接收者對象

-(id)forwardingTargetForSelector:(SEL)aSelector

在消息轉(zhuǎn)發(fā)第一次方法解析中沒有處理方法,并告訴系統(tǒng)本對象無法處理,需另尋辦法,那么系統(tǒng)會給予另外一個(gè)辦法,就是讓別的對象B來處理該問題,如果對象B能夠處理該消息,那么該消息轉(zhuǎn)發(fā)結(jié)束。
3.以其他形式實(shí)現(xiàn)該消息方法

-(NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
-(void)forwardInvocation:(NSInvocation *)anInvocation

當(dāng)前面兩個(gè)步驟都沒有處理該SEL時(shí),就會到第三個(gè)步驟,這是最后尋找IML的機(jī)會
將未知SEL作為參數(shù)傳入methodSignatureForSelector,在該方法中處理該消息,一旦能夠處理,返回方法簽名,讓后續(xù)forwardInvocation來進(jìn)行處理。
forwardInvocation可以直接切換調(diào)用目標(biāo),也就是該方法的Target。
4.直到最后未處理,拋出異常

-(void)doesNotRecognizeSelector:(SEL)aSelector

作為找不到函數(shù)實(shí)現(xiàn)的最后一步,NSObject實(shí)現(xiàn)這個(gè)函數(shù)只有一個(gè)功能,就是拋出異常。

2、Runloop 讓Runloop?;畹姆绞剑?/h1>

3、SDWebImage的緩存原理以及沙盒中四個(gè)文件夾的區(qū)別(caches文件夾特點(diǎn))?

1、SDWebImage的緩存原理

1、調(diào)用公開方法setImageWithURL:placeholderImage:options:傳入U(xiǎn)RL 開始處理圖片。
2、先從內(nèi)存圖片緩存查找是否有圖片,如果內(nèi)存中已經(jīng)有圖片緩存,SDImageCacheDelegate回調(diào)顯示圖片。
3、如果內(nèi)存緩存中沒有,生成 異步任務(wù)添加到隊(duì)列,開始從硬盤查找圖片是否已經(jīng)緩存。
4、根據(jù) URL的MD5值Key在硬盤緩存目錄下嘗試讀取圖片文件。這一步是在 NSOperation 進(jìn)行的操作,所以回主線程進(jìn)行結(jié)果回調(diào) notifyDelegate:。
5、如果從硬盤讀取到了圖片,將圖片添加到內(nèi)存緩存中(如果空閑內(nèi)存過小, 會先清空內(nèi)存緩存)。SDImageCacheDelegate回調(diào)展示圖片。
6、如果從硬盤緩存目錄讀取不到圖片,說明所有緩存都不存在該圖片,需要下載圖片。
7、共享或重新生成一個(gè)下載器 SDWebImageDownloader開始下載圖片。
8、下載過程中利用 ImageIO做了按圖片下載進(jìn)度加載效果。
9、下載完成后做圖片解碼處理。
10、解碼完成通知主線程解碼完成并回調(diào)給SDWebImageDownloader。
11、SDWebImageDownloader回調(diào)給SDWebImageManager通知下載完成。
12、SDWebImageManager回調(diào)給需要的地方展示圖片。
13、將圖片同時(shí)保存到內(nèi)存緩存和硬盤緩存中。

2、沙盒中四個(gè)文件夾的區(qū)別

1、Documents:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)會備份該目錄。
2、 tmp:保存應(yīng)用運(yùn)行時(shí)所需的臨時(shí)數(shù)據(jù),使用完畢后再將相應(yīng)的文件從該目錄刪除。應(yīng)用沒有運(yùn)行時(shí),系統(tǒng)也可能會清除該目錄下的文件。iTunes同步設(shè)備時(shí)不會備份該目錄。
3、 Library/Caches:保存應(yīng)用運(yùn)行時(shí)生成的需要持久化的數(shù)據(jù),iTunes同步設(shè)備時(shí)不會備份該目錄。一般存儲體積大、不需要備份的非重要數(shù)據(jù)。
4、Library/Preference:保存應(yīng)用的所有偏好設(shè)置,iOS的Settings(設(shè)置)應(yīng)用會在該目錄中查找應(yīng)用的設(shè)置信息。iTunes同步設(shè)備時(shí)會備份該目錄。

4、KVO實(shí)現(xiàn)原理?

參考常見面試題一

5、TCP阻塞機(jī)制?

慢啟動
擁塞規(guī)避
快速啟動
快速恢復(fù)

6、http和https的區(qū)別?

7、自定義一個(gè)類A繼承于NSObject 聲明一個(gè)方法 不實(shí)現(xiàn) 寫一個(gè)NSObject的分類去實(shí)現(xiàn)這個(gè)方法 調(diào)用時(shí)會不會出錯(cuò) 為什么 流程是什么?創(chuàng)建兩個(gè)同一個(gè)類的分類 并聲明同一個(gè)方法 會不會報(bào)錯(cuò) 為什么 怎么調(diào)用的?

都不會報(bào)錯(cuò)。
首先OC調(diào)用方法時(shí) 實(shí)際是通過消息傳遞來尋找方法的實(shí)現(xiàn) A的最終方法的實(shí)現(xiàn)會找到最終的父類NSObject 遍歷方法列表時(shí) Runtime會把分類的方法添加到本類的方法列表中 所以最終會執(zhí)行NSObject的分類方法 具體參考Runtime消息機(jī)制。
尋找方法實(shí)現(xiàn)時(shí)會把分類的方法合并到本類中,如果兩個(gè)分類中有相同的方法,后編譯的會覆蓋掉先編譯的方法。

8、內(nèi)存管理方法?

9、為什么要用MVVM RAC數(shù)據(jù)雙向綁定?

10、二分查找算法 以及時(shí)間復(fù)雜度?

11、控制器生命周期

12、有沒有使用過分類 分類的優(yōu)缺點(diǎn)是什么?

13、有沒有寫過動態(tài)庫 動態(tài)庫實(shí)現(xiàn)原理?

14、coreData和SQLite 幾萬條數(shù)據(jù)的查詢優(yōu)化(索引)?

15、圖片壓縮的一些方式?

16、視頻編碼格式原理?

17、GCD

向主隊(duì)列添加的任務(wù)要等主線程中其他任務(wù)執(zhí)行完畢再執(zhí)行。

18、異步上傳圖片保證圖片順序?

19、NSArray和NSMutableArray的操作是否線程安全?

20、weak源碼?

21、設(shè)計(jì)一個(gè)網(wǎng)絡(luò)請求包含取消網(wǎng)絡(luò)請求的方法?

22、http1.0和http1.1的區(qū)別?

23、SDWebImage異步解壓縮?

24、流媒體傳輸協(xié)議?

25、http和https的區(qū)別

26、TCP協(xié)議

27、Socket協(xié)議

28、Post和Get

29、Swift和OC的區(qū)別

30、Swift保持OC的Runtime特性

31、Charles抓包原理

32、單鏈表證明是否存在環(huán)

33、兩個(gè)單鏈表合并

34、若干不均勻的繩子 燃燒完需要一個(gè)小時(shí) 使用一個(gè)打火機(jī) 找出15分鐘

35、8個(gè)球 其中一個(gè)重一點(diǎn) 用天平幾次可以稱出來

36、OC、Swift、flutter、JS、CSS混編

37、離屏渲染原理及優(yōu)化方案

38、使用Swift實(shí)現(xiàn)字符串字母排序算法

39、組件化優(yōu)化方案

40、通過混編實(shí)現(xiàn)熱更新

41、首頁閃屏優(yōu)化方案

42、彈窗消失實(shí)現(xiàn)方案

43、AFNetworking源碼結(jié)構(gòu)

網(wǎng)絡(luò)通信模塊:URLSession
網(wǎng)絡(luò)狀態(tài)監(jiān)聽模塊:Reachability
網(wǎng)絡(luò)通信安全模塊:Security
網(wǎng)絡(luò)通信序列化模塊:Serialization

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容