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ù)鏈路層-物理層