引言
在實(shí)際iOS開發(fā)中我,我們經(jīng)常會調(diào)用alloc
方法高诺,然而對于alloc
方法的底層實(shí)現(xiàn)原理碌识,大部分人并不是很清楚。
一虱而、準(zhǔn)備工作
1筏餐、探究底層,肯定要閱讀蘋果源碼牡拇。源碼庫的下載地址:opensource或者 Source Browser魁瞪, 兩者的區(qū)別
在于Source Browser
里面的版本更新更快更詳細(xì)
穆律,搜索objc4
即得到我們索要下載的源碼。
2.源碼編譯:這里暫不討論佩番,有興趣的可以自己百度查資料众旗,這里推薦cooci大神
的github地址:https://github.com/LGCooci?tab=repositories,里面有各種版本的更新和步驟趟畏。
二贡歧、alloc流程圖結(jié)果
如下:
那么,究竟上面的流程圖
是怎樣出來的呢赋秀?我們都知道利朵,正常情況項(xiàng)目里面的這些方法名我們是不知道的,那么猎莲,探究
流程圖的思路
是什么,需要具備哪方面
的知識绍弟?
三、alloc流程圖探索過程
(1)首先我們需要了解一個概念:符號斷點(diǎn)
著洼。在我們對底層alloc
源碼一無所知
的情況下樟遣,我們只知道創(chuàng)建對象要alloc
,我們就已alloc
方法為突破口
身笤。
這里需要注意的是豹悬,需要
先進(jìn)入
到你想要看
的斷點(diǎn),再把符號斷點(diǎn)
打開液荸,切記切記
瞻佛。點(diǎn)step into
鍵的時候需要同時按住control鍵
。
在這里可以發(fā)現(xiàn)代碼進(jìn)入了objc_alloc
娇钱,繼續(xù)點(diǎn)擊step into
還會進(jìn)入一些底層的其它方法伤柄,這里不做詳細(xì)介紹。
(2)通過反匯編調(diào)試
還是先運(yùn)行到斷點(diǎn)處
文搂,再打開匯編适刀,繼續(xù)點(diǎn)擊step into+control鍵
可以從匯編里面看出,走了objc_alloc
方法煤蹭。
(3)看源碼笔喉,是最直觀
的方法,推薦大家使用疯兼。
核心代碼:
static ALWAYS_INLINE id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
int construct_flags = OBJECT_CONSTRUCT_NONE,
bool cxxConstruct = true,
size_t *outAllocatedSize = nil)
{
ASSERT(cls->isRealized());
// Read class's info bits all at once for performance
bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
bool hasCxxDtor = cls->hasCxxDtor();
bool fast = cls->canAllocNonpointer();
size_t size;
//先計(jì)算內(nèi)存空間所需要的大小然遏,在這個過程中遵循著內(nèi)存對齊規(guī)則贫途,以8字節(jié)為單位吧彪,因?yàn)槲覀兊幕緮?shù)據(jù)類型是不會超過8個字節(jié)的,最主要地是丢早,以空間換時間姨裸,讓cpu保持高效秧倾。
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;
id obj;
//alloc:向棧申請開辟內(nèi)存,返回地址指針
if (zone) {
obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
obj = (id)calloc(1, size);
}
if (slowpath(!obj)) {
if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
return _objc_callBadAllocHandler(cls);
}
return nil;
}
if (!zone && fast) {
//將申請的內(nèi)存地址指針和isa指針即我們的類綁定起來
obj->initInstanceIsa(cls, hasCxxDtor);
} else {
// Use raw pointer isa on the assumption that they might be
// doing something weird with the zone or RR.
obj->initIsa(cls);
}
if (fastpath(!hasCxxCtor)) {
return obj;
}
construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
return object_cxxConstructFromClass(obj, cls, construct_flags);
}