alloc的源碼,須要去蘋果的Source Browser下載最新的版本.markdown
能夠參考源碼編譯調試,直接在源碼基礎上跑起來,方便查看OC方法的底層實現步驟.app
alloc
方法,能夠說是最多見的類方法,在咱們建立類對象時,是不可避免要使用到alloc,有人可能要質疑了,new
不能夠建立類對象嗎? 但其實new方法,仍是會調用到alloc.oop
有過iOS開發基礎的都知道,alloc init方法,會爲要建立的對象,開闢一段內存空間並初始化類對象.那咱們來看下圖.post
由上圖咱們看到,p一、p二、p3所指向的內存空間都是相同的,也就說明,只有
alloc方法會去開闢空間,init方法沒有對開闢的內存進行過修改
spa
經過下載的objc源碼,以及源碼編譯調試
中的搭建,咱們能夠直接點進去看到alloc的源碼實現過程. 3d
_class_createInstanceFromZone
其中關鍵的三個步驟:指針
size = cls->instanceSize(extraBytes);
1.1. cache.fastInstanceSize(extraBytes)
調試
1.2. align16
code
// 其中`_flags`來自與當前類的標識,由_flags的不一樣,得出不一樣的結果,這裏咱們獲得`size = 16`.
size_t size = _flags & FAST_CACHE_ALLOC_MASK;
// extra傳進來的是0, FAST_CACHE_ALLOC_DELTA16=8 則align16(8)
// align16方法 主要作的事情是16字節對齊,而如今iOS版本要求的就是16字節對齊
// 緣由在於對象的isa指針佔據8字節,若是按照8字節對齊方式,多個對象的isa連續排列,容易形成訪問異常
// 因此最終return了 「16」, 即size = cls->instanceSize(extraBytes) = 16.
return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
複製代碼
obj = (id)calloc(1, size);
這個方法,會開闢
size個字節
的內存區域,返回obj是指向這塊內存的指針
.orm
obj->initInstanceIsa(cls, hasCxxDtor);
這個方法會將開闢的內存關聯到要建立的類對象.
alloc方法要作的事情爲
init方法都作了什麼?
由源碼咱們能夠看到,init
方法只是返回了alloc獲得的obj地址
,因此開頭案例,p一、p二、p3指向的指針都是相同的.
new
的底層調用了callALloc
,是上邊alloc
建立過程當中的其中一個方法.
可是咱們要在合適的地方使用new方法,由於它的弊端是,它沒有辦法調用重寫自定義的init方法.