iOS開發(fā)之 runtime(31) :關(guān)于 weak-linked class

logo

本系列博客是本人的源碼閱讀筆記,如果有 iOS 開發(fā)者在看 runtime 的,歡迎大家多多交流。

前言

上一篇文章我們說到添加 remap class 的兩個(gè)前提條件是 missingWeakSuperclass 或者 popFutureNamedClass 存在。今天我們?cè)敿?xì)分析一下,什么是 missingWeakSuperclass。

分析

missingWeakSuperclass 的源碼為:

/***********************************************************************
* missingWeakSuperclass
* Return YES if some superclass of cls was weak-linked and is missing.
**********************************************************************/
static bool  missingWeakSuperclass(Class cls) {
    assert(!cls->isRealized());

    if (!cls->superclass) {
        // superclass nil. This is normal for root classes only.
        return (!(cls->data()->flags & RO_ROOT));
    } else {
        // superclass not nil. Check if a higher superclass is missing.
        Class supercls = remapClass(cls->superclass);
        assert(cls != cls->superclass);
        assert(cls != supercls);
        if (!supercls) return YES;
        if (supercls->isRealized()) return NO;
        return missingWeakSuperclass(supercls);
    }
}

代碼的注釋已經(jīng)一目了然:該函數(shù)就是判斷某個(gè) class 的父類是否是 weak-linked 并且缺失了。那 什么叫做 weak-linked?比如 NSObject 是否是 weak-linbked ?很顯然不是的。那么什么是 weak-linked?

weak-linked
我們開發(fā)的時(shí)候,都會(huì)使用最新的SDK,但是為了讓老的設(shè)備可以下載并運(yùn)行我們的應(yīng)用,就要將Deployment Target設(shè)置成之前系統(tǒng)的版本號(hào)。例如我們應(yīng)用使用iOS 8.1的SDK,Deployment Target設(shè)置成iOS 5.1.1,雖然我們開發(fā)的時(shí)候使用的是8.1的SDK,但是程序運(yùn)行在的設(shè)備中卻可能是6.0 or 7.0的SDK上,按照蘋果的說法,如果我們應(yīng)用使用了最新SDK引入的特性,比如符號(hào)、函數(shù)等,那么在版本較舊的設(shè)備上就運(yùn)行不了。下面是蘋果官方文檔的一段話:
Normally, if an application uses a new feature in a framework, it is unable to run on earlier versions of the framework that do not support that feature. Such applications would either fail to launch or crash when an attempt to use the feature was made.
那么為什么我們使用最新的SDK開發(fā)的應(yīng)用卻可以運(yùn)行在舊的系統(tǒng)中呢?答案是使用了弱引用。資料里面說過,我們自己創(chuàng)建的framework,如果需要做版本兼容,那么就要對(duì)今后加入的符號(hào)等使用弱引用,使用了弱引用之后,即使在版本較舊的環(huán)境下跑,也可以運(yùn)行,只是相應(yīng)的符號(hào)是NULL,下面就是教我們?cè)鯓佣x弱引用。有一點(diǎn)需要說明的是,如果一個(gè)framework沒有為新加入的符號(hào)加入弱引用,那也不必?fù)?dān)心,我們只要在鏈接時(shí)弱引用整個(gè)framework就好,方法就是鏈接的時(shí)候使用 -weak_framework frameworkName

// weak link the function
extern int MyFunction() __attribute__((weak_import));
// weak link the variable
extern int MyVariable __attribute__((weak_import));

這么一來, missingWeakSuperclass 的作用的作用就不言而喻了:查看 cls 類的祖宗類中是否有類是 weak-linked 的,并且已經(jīng) missing,祖宗類里有 missing weak-linked 的,則 cls 的所有信息也是不可信的,所以將其添加到重映射表里,映射為nil,即 cls -> nil。

總結(jié)

本文講解了 weak-linked class 的概念以及 missingWeakSuperclass 的作用,希望對(duì)大家有所幫助。

參考

Weakly linked symbols and frameworks(弱引用符號(hào)和framework)

Frameworks and Weak Linking

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

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