[記]讀博客之筆記

每天記一下,日積月累,總會(huì)有進(jìn)步。

以下內(nèi)容都是摘自各個(gè)大牛博客

2017-03-10:

objc_msgSend做了什么?

舉個(gè)??objc_msgSend(obj, foo)是如何執(zhí)行的:

  1. 首先通過 objc 的 isa 指針找到它的 class ;
  2. 再在 class 的 method list 找到 foo ;
  3. 如果 class 中沒有找到 foo ,繼續(xù)往它的 superclass 中去找;
  4. 只要找到 foo 這個(gè)函數(shù), 就會(huì)去執(zhí)行它的 IMP.

其實(shí)也并不是每次執(zhí)行 foo 都會(huì)去這樣遍歷objc_method_list,這樣也并合理。那又是怎么做的呢?那就是objc_class中的另一個(gè)重要成員objc_cache 。它會(huì)把調(diào)用過的函數(shù)緩存下來。在找到 foo 之后,把 foo 的method_name作為 key ,method_imp作為 value 存起來了。當(dāng)再次收到 foo 消息時(shí),就可以直接在 cache 里面找到,避免去遍歷objc_method_list,從而大大的提高函數(shù)查詢的效率。

Objective-C 中給一個(gè)對(duì)象發(fā)送消息會(huì)經(jīng)過以下幾個(gè)步驟:

  1. 在對(duì)象類的 dispatch table 中嘗試找到該消息。如果找到了,跳到相應(yīng)的函數(shù)IMP中執(zhí)行代碼;
  2. 如果沒找到,Runtime 會(huì)發(fā)送+resolveInstanceMethod: (實(shí)例方法) 或者resolveClassMethod: (類方法) 嘗試去 resolve (解決) 這個(gè)消息;
  3. 如果 resolve 方法返回NO,Runtime 就會(huì)發(fā)送-forwardingTargetForSelector:允許你把這個(gè)消息轉(zhuǎn)發(fā)給另外一個(gè)對(duì)象;
  4. 如果沒新的目標(biāo)對(duì)象返回,Runtime 就會(huì)發(fā)送-methodSignatureForSelector:-forwardInvocation:消息。你可以發(fā)送-invokeWithTarget:消息來手動(dòng)轉(zhuǎn)發(fā)消息或者發(fā)送-doesNotRecognizeSelector:拋出異常。

摘自Objective-C Runtime

2017-03-24:

對(duì)于OC中的類來說,在runtime中會(huì)有兩個(gè)方法被調(diào)用:

+load
+initialize
這兩個(gè)方法看起來都是在類初始的時(shí)候調(diào)用的,但其實(shí)還是有一些異同,從而可以用來做一些行為。

+load

首先,load方法是一定會(huì)在runtime中被調(diào)用的,只要類被添加到runtime中了,就會(huì)調(diào)用load方法,所以我們可以自己實(shí)現(xiàn)laod方法來在這個(gè)時(shí)候執(zhí)行一些行為。

而且有意思的一點(diǎn)是,load方法不會(huì)覆蓋。也就是說,如果子類實(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í)候。也就是說這個(gè)方法是懶加載,沒有用到這個(gè)類就不會(huì)調(diào)用,可以節(jié)省系統(tǒng)資源。

還有一點(diǎn)截然相反,卻更符合我們預(yù)期的就是,initialize方法會(huì)覆蓋。也就是說如果子類實(shí)現(xiàn)了initialize方法,就不會(huì)執(zhí)行父類的了,直接執(zhí)行子類本身的。如果分類實(shí)現(xiàn)了initialize方法,也不會(huì)再執(zhí)行主類的。所以initialize方法的執(zhí)行覆蓋順序是 分類 -> 子類 ->類。且只會(huì)有一個(gè)initialize方法被執(zhí)行。

摘自OC中l(wèi)oad方法和initialize方法的異同

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

摘自CocoChina

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ù)組中,那么說明,實(shí)際上我們的控件對(duì)象是屬于view的,也就是說view對(duì)加到它上面的控件是強(qiáng)引用。當(dāng)我們使用Outlet屬性的時(shí)候,我們是在viewController里面使用,而這個(gè)Outlet屬性是有view來進(jìn)行強(qiáng)引用的,我們?cè)趘iewController里面僅僅是對(duì)其使用,并沒有必要擁有它,所以是weak的

2017-07-06

weakSelf和strongSelf

weakSelf 是為了block不持有self,避免Retain Circle循環(huán)引用。在 Block 內(nèi)如果需要訪問 self 的方法、變量,建議使用 weakSelf。

strongSelf的目的是因?yàn)橐坏┻M(jìn)入block執(zhí)行,假設(shè)不允許self在這個(gè)執(zhí)行過程中釋放,就需要加入strongSelf。block執(zhí)行完后這個(gè)strongSelf 會(huì)自動(dòng)釋放,沒有不會(huì)存在循環(huán)引用問題。如果在 Block 內(nèi)需要多次 訪問 self,則需要使用 strongSelf

摘自深入研究Block用weakSelf、strongSelf、@weakify、@strongify解決循環(huán)引用

2017-07-31

block的生命周期?

block是一個(gè)對(duì)象,它的生命周期很簡(jiǎn)單,只要看持有block的對(duì)象是不是也被block持有。如果沒有持有,就不用擔(dān)心循環(huán)引用的問題。

如何解決blcok產(chǎn)生的循環(huán)引用?

可以用__weak(ARC)__block(MRC)來解決。

block對(duì)于參數(shù)形式傳進(jìn)來的對(duì)象,會(huì)不會(huì)強(qiáng)引用?

其實(shí)block與函數(shù)一樣,對(duì)于傳進(jìn)來的參數(shù),并不會(huì)持有。

摘自讓我們來深入淺出block吧

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

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

  • 轉(zhuǎn)至元數(shù)據(jù)結(jié)尾創(chuàng)建: 董瀟偉,最新修改于: 十二月 23, 2016 轉(zhuǎn)至元數(shù)據(jù)起始第一章:isa和Class一....
    40c0490e5268閱讀 2,049評(píng)論 0 9
  • 1.@property 后面可以有哪些修飾符 第一種:控制set方法的內(nèi)存管理:retain strong ass...
    allen852閱讀 602評(píng)論 0 0
  • 說明:面試題來源是微博@我就叫Sunny怎么了的這篇博文:《招聘一個(gè)靠譜的 iOS》,其中共55題,除第一題為糾錯(cuò)...
    __Lex閱讀 839評(píng)論 0 4
  • 《黎明有你》 -- 杏子 你別懼怕黑夜, 黑夜之后, 有更可怕的黑洞。 你別賭注陽光, 陽光也會(huì)反噬你愛的藍(lán)天。 ...
    一種缺陷ing閱讀 259評(píng)論 2 3
  • 校區(qū):科學(xué)創(chuàng)想樂高機(jī)器人和平校區(qū) 時(shí)間:周日10:00-12:00 學(xué)員:孟令軒 任教老師:楊玲 教學(xué)目標(biāo): 1....
    Happy00閱讀 1,129評(píng)論 0 0

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