iOS面試題匯總(一)

1 ARC和MRC的區(qū)別

ARC自動的引用計(jì)數(shù),LVVM編譯器會在“編譯”的時(shí)候 幫我們在代碼合適的地方添加release、retarn、autorelease等添加計(jì)數(shù)器或者減少計(jì)數(shù)器操作

MRC手動的引用計(jì)數(shù),需要程序員手動的去release,retine。


2 App的啟動分為哪幾種

1 冷啟動:App重啟后啟動,不再內(nèi)存里也沒有進(jìn)程存在。

2 熱啟動:App最近結(jié)束后再啟動,有部分在內(nèi)存但沒有進(jìn)程存在。

3 重啟:APP沒結(jié)束,只是暫停,全在內(nèi)存中,進(jìn)程也存在。


3 +load方法

1 調(diào)用時(shí)機(jī)是在AppDelegate前

2 load方法的調(diào)用順序

? ?2.1 父類子類都實(shí)現(xiàn)了load方法的話,兩者的都會被調(diào)用,父類的先調(diào)用,子類的后調(diào)用。

? ?2.2 如果子類未實(shí)現(xiàn)load方法,在加載該子類,不會再調(diào)用父類的方法。

? ?2.3 如果類和 category都實(shí)現(xiàn)了load方法,類先執(zhí)行,category后執(zhí)行。

? ?2.4 當(dāng)多個(gè)category都實(shí)現(xiàn)了load方法,都會執(zhí)行,順序和Compile Sources 中的的順序有關(guān)。

? ?2.5 load方法是Runtime直接拿到load的IMP直接去調(diào)用的。


4?category相關(guān)

如果category添加與原類相同的同名方法,會覆蓋原類的方法,只執(zhí)行分類的方法。

當(dāng)多個(gè)category有同樣名稱的分類方法名稱時(shí),誰在最后編譯就執(zhí)行誰。


5 ?category和Extension的區(qū)分

? 5.1?category分類中只能擴(kuò)充方法,不能擴(kuò)展屬性和成員變量(寫成員變量會直接報(bào)錯),通過runtime可以強(qiáng)加屬性,

? 5.2?category分類聲明了一個(gè)屬性,那么分類只會生成這個(gè)屬性的set,get方法聲明。


6 Block類型

? ?6.1 GlobalBlock 存儲在數(shù)據(jù)區(qū)

? ?6.2 ?StackBlock 存儲在棧區(qū)

? ?6.3 MallocBlock 存儲在堆區(qū)

? ?3種block的場景

? ?// 1. 內(nèi)部沒有調(diào)用外部變量的blockvoid(^block1)(void)=^{NSLog(@"Hello");};

? ? // 2. 內(nèi)部調(diào)用外部變量的blockinta=10; void(^block2)(void)=^{NSLog(@"Hello - %d",a);};

? ?// 3. 直接調(diào)用的block的classNSLog(@"%@ %@ %@",[block1 class],[block2 class],[^{NSLog(@"%d",a);}class]);

1?GlobalBlock 2?StackBlock 3?MallocBlock

什么情況下blcok會被拷貝

在ARC下,將一個(gè)Block賦值給一個(gè)非__weak修飾的變量會執(zhí)行拷貝外,還有以下情況會執(zhí)行:

顯式調(diào)用Block的copy方法時(shí);

賦值給一個(gè)具有copy修飾的Block屬性時(shí);

在ARC下,向函數(shù)或者方法傳遞Block時(shí)(MRC下需要手動copy);

調(diào)用Coaca框架中方法名中含有usingBlock的方法時(shí);

調(diào)用GCD的API時(shí)。


7 AutoreleasePool

? ?AutoreleasePool使用的是 AutoreleasePoolPage管理,AutoreleasePoolPage是一個(gè)雙向的鏈表,除了用來存放內(nèi)部的成員變量,剩下的空間都會用來存放autorelease對象的地址,autoreleasepool會自動釋放內(nèi)存。


8 OC的消息機(jī)制

消息傳遞:

1 方法的調(diào)用會通過發(fā)送消息來調(diào)用 “objc_msgSend”來傳遞


2 第一步 根據(jù)對象(類對象,實(shí)例對象)的isa的指針找到所屬的類


3 第二步 根據(jù)類對象里面的catch方法列表進(jìn)行查找,根據(jù)Selector方法名來獲取對應(yīng)的IMP,開始調(diào)用。


3 第三步 如果沒找到對應(yīng)的實(shí)現(xiàn)IMP,會繼續(xù)查找類對象里面的class_rw_t里面的methods(方法列表),從而遍歷,找到方法所屬的IMP,如果找到了就是添加到catch表里面,然后調(diào)用不再進(jìn)行下一步。


4 第四步 如果第三步也沒有找到,會根據(jù)類對象里面的superclass(父類)指針,查找父類的catch,如果還沒有找到,會繼續(xù)查找到父類的class_rw_t里面的methodslist(方法列表),從而遍歷,找到方法所屬的IMP,如果查找到則會添加到catch表里面


5 第五部 如果四步?jīng)]有找到,就繼續(xù)找到元類。


6 第六步,如果元類還沒有找到,就會找到nsobject里面,如果再沒有找到,就進(jìn)入動態(tài)解析里面。


動態(tài)解析:

1 當(dāng)消息傳遞,沒有找到對應(yīng)的IMP的時(shí)候,就會進(jìn)入動態(tài)解析中。


2 第一步會調(diào)用 ?+(BOOL)resolveClassMethod:(SEL)sel; 類方法

? ? ? ? ? ? ? ? ? ? ? ? ? ??+(BOOL)resolveInstanceMethod:(SEL)sel; ?實(shí)例方法


? ? ?2.1 ?我們可以通過“runtime的class_addMethod"實(shí)現(xiàn)這兩個(gè)方法來添加對應(yīng)的IMP


? ? ?2.2 ?如果添加后,返回true,沒有添加則調(diào)用父類方法。


? ? ?2.3 注意:其實(shí)返回true或者false,結(jié)果都是一樣的,再次調(diào)消息傳遞步驟。

3 第二部:

? ?3.1 會調(diào)用 -(id)forwardingTargetForSelector:(SEL)aSelector方法,我們可以在這里返回一個(gè)響應(yīng)aSelector的對象。當(dāng)返回不為nil的時(shí)候,系統(tǒng)會繼續(xù)再次走消息方法,繼續(xù)查找對應(yīng)的IMP

? ?3.2 如果第一步返回nil或者self,此時(shí)系統(tǒng)會繼續(xù)走這里-(NSMethodSignature*)methodSignatureForSelector:(SEL)aSelector,需要返回aSelector的一個(gè)簽名

3.3 如果返回了簽名,就會到這里-(void)forwardInvocation:(NSinvocation*)anInvocation,相應(yīng)的我們可以根據(jù)anInvocation,可以獲取到參數(shù),target,方法名等,再次操作的空間就很多了。

9 weak屬性是怎么實(shí)現(xiàn)的 ?

9.1使用weak關(guān)鍵字修飾的對象在銷毀的時(shí)候,指針會置為nil,而weak的底層是將指針和對象以key-value的形式存入哈希表,使用__weak的時(shí)候,底層會調(diào)用 id objc_storeWeak(id * location, id newobj)傳遞兩個(gè)參數(shù)。第一個(gè)參數(shù)為指針,第二個(gè)參數(shù)是指針指向的對象。

9.2 繼續(xù)調(diào)用storeWeak(location,(objc_object *)newObj)

第一個(gè)參數(shù)是指針,第二個(gè)參數(shù)是對象的地址

再次方法里面會根據(jù)對象地址生成一個(gè)SlideTables對象

9.3 調(diào)用 id weak_register_no_lock(weak_table_t *weak_table, id referent_id, id *referrer_id,bool crashIfDeallocting)

? ? ? weak_table則為slideTables的一個(gè)屬性,referent_id為對象,referrer_id則為那個(gè)弱應(yīng)用的指針

? ? ?在里面會根據(jù)對象地址和指針生成一個(gè)weak_entry_t

9.4 會繼續(xù)調(diào)用static void weak_entry_insert(weak_table_t ?*weak_table, weak_entry_t*new_entry)


10 App啟動流程及優(yōu)化

? ? ? App的啟動流程

? ? ?10.1 解析info.plist

? ? ? ? ? ? ? 加載相關(guān)信息,例如閃頻

? ? ? ? ? ? ? 沙箱(sandbox)建立,權(quán)限檢查。

? ? 10.2 Mach-0加載

? ? ? ? ? ? 如果是胖二進(jìn)制文件,尋找合適當(dāng)前CPU類別的部分

? ? ? ? ? ? 加載所有依賴的Mack-0文件(遞歸調(diào)用Mach-0加載的方法)

? ? ? ? ? ? ?定位內(nèi)部,外部指針引用,例如字符串,函數(shù)等

? ? ? ? ? ? ?實(shí)行聲明為_attribute_((constructor))的C函數(shù)

? ? ? ? ? ? ?加載分類(category)中的方法

? ? ? ? ? ? ?C++靜態(tài)對象加載,調(diào)用objc的+load函數(shù)

? ?10.3 程序執(zhí)行階段

? ? ? ? ? ? 調(diào)用main()

? ? ? ? ? ? 調(diào)用UIApplicationMain()

? ? ? ? ? ? 調(diào)用applicationWillFinishLaunching代理方法


11 不同類型的對象用copy還是strong ? ?

NSArray,NSString用copy 會執(zhí)行深拷貝,從新分配內(nèi)存,不會影響之前的,用strong的話是指針拷貝,會改變原來的。

NSMutableArray,NSMutableDictionary 用strong,用copy的話會變?yōu)椴豢勺冾愋?,增刪改查會報(bào)錯。


12 網(wǎng)絡(luò)7層協(xié)議從高到底

? ? ? ?應(yīng)用層-表示層-會話層-傳輸層-網(wǎng)絡(luò)層-數(shù)據(jù)鏈路層-物理層

最后編輯于
?著作權(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ù)。

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