本系列博客是本人的源碼閱讀筆記烈拒,如果有 iOS 開發(fā)者在看 runtime 的嚷量,歡迎大家多多交流陋桂。
前言
上一篇文章我們說到添加 remap class 的兩個前提條件是 missingWeakSuperclass 或者 popFutureNamedClass 存在。今天我們詳細(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ù)就是判斷某個 class 的父類是否是 weak-linked 并且缺失了。那 什么叫做 weak-linked抖所?比如 NSObject 是否是 weak-linbked 梨州?很顯然不是的。那么什么是 weak-linked田轧?
weak-linked
我們開發(fā)的時候暴匠,都會使用最新的SDK,但是為了讓老的設(shè)備可以下載并運(yùn)行我們的應(yīng)用傻粘,就要將Deployment Target設(shè)置成之前系統(tǒng)的版本號每窖。例如我們應(yīng)用使用iOS 8.1的SDK,Deployment Target設(shè)置成iOS 5.1.1弦悉,雖然我們開發(fā)的時候使用的是8.1的SDK窒典,但是程序運(yùn)行在的設(shè)備中卻可能是6.0 or 7.0的SDK上,按照蘋果的說法稽莉,如果我們應(yīng)用使用了最新SDK引入的特性瀑志,比如符號、函數(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,如果需要做版本兼容将饺,那么就要對今后加入的符號等使用弱引用贡避,使用了弱引用之后,即使在版本較舊的環(huán)境下跑予弧,也可以運(yùn)行刮吧,只是相應(yīng)的符號是NULL,下面就是教我們怎樣定義弱引用掖蛤。有一點(diǎn)需要說明的是杀捻,如果一個framework沒有為新加入的符號加入弱引用,那也不必?fù)?dān)心蚓庭,我們只要在鏈接時弱引用整個framework就好致讥,方法就是鏈接的時候使用 -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 的作用爽锥,希望對大家有所幫助涌韩。