每天記一下,日積月累况褪,總會(huì)有進(jìn)步。
以下內(nèi)容都是摘自各個(gè)大牛博客
2017-03-10:
objc_msgSend
做了什么?
舉個(gè)??
objc_msgSend(obj, foo)
是如何執(zhí)行的:
- 首先通過(guò) objc 的 isa 指針找到它的 class 罐寨;
- 再在 class 的 method list 找到 foo ;
- 如果 class 中沒(méi)有找到 foo ,繼續(xù)往它的 superclass 中去找序矩;
- 只要找到 foo 這個(gè)函數(shù)鸯绿, 就會(huì)去執(zhí)行它的 IMP.
其實(shí)也并不是每次執(zhí)行 foo 都會(huì)去這樣遍歷
objc_method_list
,這樣也并合理簸淀。那又是怎么做的呢瓶蝴?那就是objc_class
中的另一個(gè)重要成員objc_cache
。它會(huì)把調(diào)用過(guò)的函數(shù)緩存下來(lái)租幕。在找到 foo 之后舷手,把 foo 的method_name
作為 key ,method_imp
作為 value 存起來(lái)了令蛉。當(dāng)再次收到 foo 消息時(shí)聚霜,就可以直接在 cache 里面找到狡恬,避免去遍歷objc_method_list
,從而大大的提高函數(shù)查詢的效率蝎宇。
Objective-C 中給一個(gè)對(duì)象發(fā)送消息會(huì)經(jīng)過(guò)以下幾個(gè)步驟:
- 在對(duì)象類的 dispatch table 中嘗試找到該消息弟劲。如果找到了,跳到相應(yīng)的函數(shù)IMP中執(zhí)行代碼姥芥;
- 如果沒(méi)找到兔乞,Runtime 會(huì)發(fā)送
+resolveInstanceMethod:
(實(shí)例方法) 或者resolveClassMethod:
(類方法) 嘗試去 resolve (解決) 這個(gè)消息;- 如果 resolve 方法返回NO凉唐,Runtime 就會(huì)發(fā)送
-forwardingTargetForSelector:
允許你把這個(gè)消息轉(zhuǎn)發(fā)給另外一個(gè)對(duì)象庸追;- 如果沒(méi)新的目標(biāo)對(duì)象返回,Runtime 就會(huì)發(fā)送
-methodSignatureForSelector:
和-forwardInvocation:
消息台囱。你可以發(fā)送-invokeWithTarget:
消息來(lái)手動(dòng)轉(zhuǎn)發(fā)消息或者發(fā)送-doesNotRecognizeSelector:
拋出異常淡溯。
2017-03-24:
對(duì)于OC中的類來(lái)說(shuō),在runtime中會(huì)有兩個(gè)方法被調(diào)用:
+load
+initialize
這兩個(gè)方法看起來(lái)都是在類初始的時(shí)候調(diào)用的簿训,但其實(shí)還是有一些異同咱娶,從而可以用來(lái)做一些行為。
+load
首先强品,load方法是一定會(huì)在runtime中被調(diào)用的膘侮,只要類被添加到runtime中了,就會(huì)調(diào)用load方法的榛,所以我們可以自己實(shí)現(xiàn)laod方法來(lái)在這個(gè)時(shí)候執(zhí)行一些行為琼了。
而且有意思的一點(diǎn)是,load方法不會(huì)覆蓋夫晌。也就是說(shuō)雕薪,如果子類實(shí)現(xiàn)了load方法,那么會(huì)先調(diào)用父類的load方法慷丽,然后又去執(zhí)行子類的load方法蹦哼。同樣的鳄哭,如果分類實(shí)現(xiàn)了load方法要糊,也會(huì)先執(zhí)行主類的load方法,然后又會(huì)去執(zhí)行分類的load方法妆丘。所以父類的load會(huì)執(zhí)行很多次锄俄,這一點(diǎn)需要注意。而且執(zhí)行順序是 類 -> 子類 ->分類勺拣。而不同類之間的順序不一定奶赠。
+initialize
與load不同的是,initialize方法不一定會(huì)執(zhí)行药有。只有當(dāng)一個(gè)類第一次被發(fā)送消息的時(shí)候會(huì)執(zhí)行毅戈,注意是第一次苹丸。什么叫發(fā)送消息呢,就是執(zhí)行類的一些方法的時(shí)候苇经。也就是說(shuō)這個(gè)方法是懶加載赘理,沒(méi)有用到這個(gè)類就不會(huì)調(diào)用,可以節(jié)省系統(tǒng)資源扇单。
還有一點(diǎn)截然相反商模,卻更符合我們預(yù)期的就是,initialize方法會(huì)覆蓋蜘澜。也就是說(shuō)如果子類實(shí)現(xiàn)了initialize方法施流,就不會(huì)執(zhí)行父類的了,直接執(zhí)行子類本身的鄙信。如果分類實(shí)現(xiàn)了initialize方法瞪醋,也不會(huì)再執(zhí)行主類的。所以initialize方法的執(zhí)行覆蓋順序是 分類 -> 子類 ->類装诡。且只會(huì)有一個(gè)initialize方法被執(zhí)行趟章。
2017-03-15:
一個(gè)拓展,獲取任意ViewController的navigationController
@implementation UIViewController (IMYPublic)
- (UINavigationController*)imy_navigationController {
UINavigationController* nav = nil;
if ([self isKindOfClass:[UINavigationController class]]) {
nav = (id)self;
}
else {
if ([self isKindOfClass:[UITabBarController class]]) {
nav = [((UITabBarController*)self).selectedViewController imy_navigationController];
}
else {
nav = self.navigationController;
}
}
return nav;
}
@end
2017-07-04
為什么IBOutlet屬性是weak的慎王?
因?yàn)楫?dāng)我們將控件拖到Storyboard上蚓土,相當(dāng)于新創(chuàng)建了一個(gè)對(duì)象,而這個(gè)對(duì)象是加到視圖控制器的view上赖淤,view有一個(gè)subViews屬性蜀漆,這個(gè)屬性是一個(gè)數(shù)組,里面是這個(gè)view的所有子view咱旱,而我們加的控件就位于這個(gè)數(shù)組中确丢,那么說(shuō)明,實(shí)際上我們的控件對(duì)象是屬于view的吐限,也就是說(shuō)view對(duì)加到它上面的控件是強(qiáng)引用鲜侥。當(dāng)我們使用Outlet屬性的時(shí)候,我們是在viewController里面使用诸典,而這個(gè)Outlet屬性是有view來(lái)進(jìn)行強(qiáng)引用的描函,我們?cè)趘iewController里面僅僅是對(duì)其使用,并沒(méi)有必要擁有它狐粱,所以是weak的
2017-07-06
weakSelf和strongSelf
weakSelf 是為了block不持有self舀寓,避免Retain Circle循環(huán)引用。在 Block 內(nèi)如果需要訪問(wèn) self 的方法肌蜻、變量互墓,建議使用 weakSelf。
strongSelf的目的是因?yàn)橐坏┻M(jìn)入block執(zhí)行蒋搜,假設(shè)不允許self在這個(gè)執(zhí)行過(guò)程中釋放篡撵,就需要加入strongSelf判莉。block執(zhí)行完后這個(gè)strongSelf 會(huì)自動(dòng)釋放,沒(méi)有不會(huì)存在循環(huán)引用問(wèn)題育谬。如果在 Block 內(nèi)需要多次 訪問(wèn) self骂租,則需要使用 strongSelf
摘自深入研究Block用weakSelf、strongSelf斑司、@weakify渗饮、@strongify解決循環(huán)引用
2017-07-31
block的生命周期?
block
是一個(gè)對(duì)象宿刮,它的生命周期很簡(jiǎn)單互站,只要看持有block
的對(duì)象是不是也被block
持有。如果沒(méi)有持有僵缺,就不用擔(dān)心循環(huán)引用的問(wèn)題胡桃。
如何解決blcok產(chǎn)生的循環(huán)引用?
可以用
__weak(ARC)
或__block(MRC)
來(lái)解決磕潮。
block對(duì)于參數(shù)形式傳進(jìn)來(lái)的對(duì)象翠胰,會(huì)不會(huì)強(qiáng)引用?
其實(shí)
block
與函數(shù)一樣自脯,對(duì)于傳進(jìn)來(lái)的參數(shù)之景,并不會(huì)持有。