OC底層原理01:alloc方法底層探索

objc源碼

alloc的源碼,須要去蘋果的Source Browser下載最新的版本.markdown

能夠參考源碼編譯調試,直接在源碼基礎上跑起來,方便查看OC方法的底層實現步驟.app


alloc

alloc方法,能夠說是最多見的類方法,在咱們建立類對象時,是不可避免要使用到alloc,有人可能要質疑了,new不能夠建立類對象嗎? 但其實new方法,仍是會調用到alloc.oop

  • 那麼,alloc都作了什麼?

有過iOS開發基礎的都知道,alloc init方法,會爲要建立的對象,開闢一段內存空間並初始化類對象.那咱們來看下圖.post

由上圖咱們看到,p一、p二、p3所指向的內存空間都是相同的,也就說明,只有alloc方法會去開闢空間,init方法沒有對開闢的內存進行過修改spa

  • 再深刻探索如下:alloc是如何開闢空間的呢?

經過下載的objc源碼,以及源碼編譯調試中的搭建,咱們能夠直接點進去看到alloc的源碼實現過程. 3d

重點_class_createInstanceFromZone


其中關鍵的三個步驟:指針

    1. 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);

複製代碼

    1. obj = (id)calloc(1, size);

這個方法,會開闢size個字節的內存區域,返回obj是指向這塊內存的指針.orm


    1. obj->initInstanceIsa(cls, hasCxxDtor);

這個方法會將開闢的內存關聯到要建立的類對象.

總結:

alloc方法要作的事情爲

  1. 由系統計算出開闢的內存空間大小
  2. 申請開闢得出的大小內存空間,獲得isa指針
  3. 將開闢的內存空間與要建立的類對象進行關聯


init

init方法都作了什麼?

由源碼咱們能夠看到,init方法只是返回了alloc獲得的obj地址,因此開頭案例,p一、p二、p3指向的指針都是相同的.


new

new的底層調用了callALloc,是上邊alloc建立過程當中的其中一個方法.

可是咱們要在合適的地方使用new方法,由於它的弊端是,它沒有辦法調用重寫自定義的init方法.

相關文章
相關標籤/搜索