在以前的博客中,對OC底層進行了一系列的探索分析,相信小夥伴們都學到了必定的知識,可是底層源碼分析比較枯燥,那麼本次就對一些面試題進行分析。 c++
在上篇博客iOS底層探索之類的加載(四):類的關聯對象AssociatedObject中主要講了類的擴展
和類的關聯對象
,移除關聯
尚未講,這裏就作一點補充。面試
objc_removeAssociatedObjects
void objc_removeAssociatedObjects(id object)
{
if (object && object->hasAssociatedObjects()) {
_object_remove_assocations(object, /*deallocating*/false);
}
}
複製代碼
_object_remove_assocations
void
_object_remove_assocations(id object, bool deallocating)
{
ObjectAssociationMap refs{};
{
AssociationsManager manager;
AssociationsHashMap &associations(manager.get());
AssociationsHashMap::iterator i = associations.find((objc_object *)object);
if (i != associations.end()) {
refs.swap(i->second);
// If we are not deallocating, then SYSTEM_OBJECT associations are preserved.
bool didReInsert = false;
if (!deallocating) {
for (auto &ref: refs) {
if (ref.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
i->second.insert(ref);
didReInsert = true;
}
}
}
if (!didReInsert)
associations.erase(i);
}
}
// Associations to be released after the normal ones.
SmallVector<ObjcAssociation *, 4> laterRefs;
// release everything (outside of the lock).
for (auto &i: refs) {
if (i.second.policy() & OBJC_ASSOCIATION_SYSTEM_OBJECT) {
// If we are not deallocating, then RELEASE_LATER associations don't get released.
if (deallocating)
laterRefs.append(&i.second);
} else {
i.second.releaseHeldValue();
}
}
for (auto *later: laterRefs) {
later->releaseHeldValue();
}
}
複製代碼
上面👆這是移除關聯對象的代碼,這裏就不過多分析源碼了,咱們看看在哪裏調用了數組
在對象的生命週期,
dealloc
的時候markdown
dealloc
// Replaced by NSZombies
- (void)dealloc {
_objc_rootDealloc(self);
}
複製代碼
_objc_rootDealloc
void
_objc_rootDealloc(id obj)
{
ASSERT(obj);
obj->rootDealloc();
}
複製代碼
對象釋放就會去找rootDealloc
app
rootDealloc
inline void
objc_object::rootDealloc()
{
if (isTaggedPointer()) return; // fixme necessary?
if (fastpath(isa.nonpointer &&
!isa.weakly_referenced &&
!isa.has_assoc &&
#if ISA_HAS_CXX_DTOR_BIT
!isa.has_cxx_dtor &&
#else
!isa.getClass(false)->hasCxxDtor() &&
#endif
!isa.has_sidetable_rc))
{
assert(!sidetable_present());
free(this);
}
else {
object_dispose((id)this);
}
}
複製代碼
這裏會判斷isa.nonpointer
、弱引用isa.weakly_referenced
、關聯對象isa.has_assoc
等等,有的話就進入object_dispose
。ide
object_dispose
id
object_dispose(id obj)
{
if (!obj) return nil;
objc_destructInstance(obj);
free(obj);
return nil;
}
複製代碼
進入objc_destructInstance
銷燬實例函數
objc_destructInstance
void *objc_destructInstance(id obj)
{
if (obj) {
// Read all of the flags at once for performance.
bool cxx = obj->hasCxxDtor();
bool assoc = obj->hasAssociatedObjects();
// This order is important.
if (cxx) object_cxxDestruct(obj);
if (assoc) _object_remove_assocations(obj, /*deallocating*/true);
obj->clearDeallocating();
}
return obj;
}
複製代碼
C++
方法,關聯對象
方法判斷,就去走_object_remove_assocations
也就是最開頭的那個移除關聯對象方法。oop
因此,關聯對象不須要咱們手動移除,會在
dealloc
時自動進行釋放源碼分析
load
是在dyld
回調load_images
中進行調用的,這個回調是在_objc_init
的過程當中進行註冊的。C++
構造函數對於同一個image
而言是在load
回調後dyld
調用的。(並非絕對的)image
內部是先加載全部類的+ load
,再加載分類的+ load
,最後加載C++
全局構造函數。(類load
-> 分類load
-> C++
構造函數)。+load
是objc
中調用的,C++
全局構造函數是在dyld
中調用的。(image
內部的順序默認是按Compile Sources
中順序進行加載的,固然對於有依賴庫的image
,依賴庫+load先被調用)。Dyld
初始化image
是按Link Binary With Libraries
順序逐個初始化的,從下標1開始,最後再初始化主程序(下標0)。image
而言C++
構造函數在load
以後調用並非絕對的。好比objc
系統庫,在進行dyld
註冊回調以前調用了自身庫的C++
構造函數(自啓)。runtime
是由C
和C++
/ 彙編
實現的⼀套API
,爲OC
語⾔加⼊了⾯向對象,運⾏時的功能。dyld
、彙編
、objc
、macho
纔是底層。OC
代碼,在程序運行過程當中,其實最終會轉換成Runtime
的C
語言代 碼,Runtime
是 Objective-C
的幕後工做者。initialize
是在第一次發送消息的時候進行的調用。學習
load
是在load_images的時候調用的,load
比initialize
調用時機早(initialize
在lookupimporforward
慢速消息查找的時候調用)。
整個調用順序load
> C++構造函數
> initialize
。
同名分類方法調用順序分爲兩種狀況:
在iOS底層探索之類的加載(三): attachCategories分析博客裏面也介紹了分類和load方法的一些加載。
首先咱們來看看什麼是分類和擴展
category
: 類別/分類
- 專門用來給類添加新的方法
- 不能給類添加成員屬性,添加了成員變量,也沒法取到
注意
:其實能夠經過runtime
給分類添加屬性- 分類中用
@property
定義變量,只會生成變量的getter,setter
方法的聲明,不能生成方法實現和帶下劃線的成員變量
。
extension
:類擴展
- 能夠說成是特殊的分類,也稱做
匿名分類
- 能夠給類添加
成員屬性
,可是是私有變量
- 能夠給類添加方法,也是
私有方法
分類咱們已經很熟悉了,這裏就沒必要過多贅述了,下面介紹下擴展
extension
類擴展,咱們平時用的是很是多的,以下
what ? 什麼,這就是擴展嗎?每天用竟然不知道!
是的,這就是擴展,平時用的是很是之多,可是不少人都不知道。
注意
:類擴展要放在聲明以後,實現以前,不然會報錯。
更多內容持續更新
🌹 喜歡就點個贊吧👍🌹
🌹 以爲有收穫的,能夠來一波,收藏+關注,評論 + 轉發,以避免你下次找不到我😁🌹
🌹歡迎你們留言交流,批評指正,互相學習😁,提高自我🌹