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