如果您在看這篇博客時候,還沒看過我上一篇博客,需要您去耐心的看一下,有助于更快更好的理解這篇博客的內(nèi)容Runtime學習基礎(chǔ)之isa指針
好,我們繼續(xù)上篇博客繼續(xù)說:我們先用結(jié)構(gòu)體解決這個問題
,請看下面的代碼
這里我們定義一個結(jié)構(gòu)體,里面存儲3個參數(shù),我們看一下結(jié)果能不能解決這個問題:請看下面的代碼截圖
這個明顯是解決了情況,大家可以嘗試其他情況,接下來,我們就引入今天最重要的模塊,就是共同體union
首先我們先看我們這個需求怎么用共用體union來解決,這里我直接寫結(jié)果,等會再一起討論蘋果的源碼,它也是這么來解決的,因為我們還知道,位運算效率是非常高的,所以請看下圖:
這個也可以很好的解決問題,至于結(jié)果我就不截圖了,大家可以試試,肯定是可以解決這個問題,另外,我上圖的綠色部分是可以注釋的,也就是有沒有綠色都是成功的,說明,綠色部分就是類似一個注解給給我們自己可以看得清楚.
蘋果源碼解讀
好了,有了上面的基礎(chǔ),相信我們很容易理解蘋果的源碼了,我們現(xiàn)在去看看.因為它的實現(xiàn)就是objc_object 我們搜索這個就能找到.
我們先來看下蘋果的源碼,因為我們知道,蘋果的arm64以后對isa做了一些優(yōu)化,之前的class里面只有一個isa指針,從之前我們學習的,一個isa是8bit也就是64位,明顯用這么多位存儲一個isa是有些浪費,所以就加了很多其他的東西,我們先看源碼如下圖:
上面的點進去看看截圖,也就是箭頭指的那個struct結(jié)構(gòu)體里面的ISA_BITFIELD這個
我們是找arm64對應(yīng)的,看看圖上的藍色的,是不是非常熟悉,跟我們定義的一摸一樣的方法,這里我把綠色框框里面的東西是做什么的,全部寫出來了,大家可以看看
我們知道一個isa是占用8bit也就是64位,我們看看上面用了多少位1+1+1+33+6+1+1+1+19=64正好是64全部用上了
現(xiàn)在我們來驗證之前的一個問題,在這個博客中寫到深入探究對象的isa指針指向哪里
請看下面截圖
之前的博客是直接寫,并沒有證明是為什么.現(xiàn)在說一下,
證明獲取isa為什么要&ISA_MASK
由這2篇博客,大家知道怎么去取某個位上的數(shù)字了吧,比如我現(xiàn)在想知道isa里面的nonpointer是多少,我們是不是很好取出來,我們直接拿到這個這個地址&1是不是就行了?對吧
那我們之前&ISA_MASK掩碼大家知道為什么了吧,現(xiàn)在我們來看看這個掩碼是多少,我們猜測肯定是前三位是000,后面是33個1,因為是取出33位,好我們?nèi)タ纯词遣皇?,先看ISA_MASK是多少
,我們用計算器看一下2進制是多少
這個二進制算出來,對應(yīng)的正好33個1,所以&這個掩碼,正好可以取出isa的cls的地址,這下大家知道為什么要&這個掩碼才能取出這個值吧!
那我們現(xiàn)在就看一個我上個博客說的,cls的后三位永遠是0
isa的內(nèi)存地址中,后三位永遠是0
其實上面已經(jīng)證明了,下面我們就來看看(大家記得用真機運行測試比較嚴謹,因為是arm64),我這邊就不用真機了,大家看一下就行了
好了,相信到這里,上篇博客的四個問題都是可以解答的了,對于isa相信大家比之前的理解更深刻了,如果面試官問isa相信你更能答到本質(zhì)!
拓展
其實我們位運行有很多值,比如我們的枚舉值,我們在iOS開發(fā)中,我們在傳枚舉值中的任何一個或者多個,蘋果底層是怎么知道我們傳入的是哪一個呢?這個就是用到位運算來處理的,具體的大家可以自己寫一個demo測試
我們要想更好的學習runtime,我們還要學習class的類結(jié)構(gòu),也要清楚知道內(nèi)部是什么樣的,這樣才能學好runtime,雖然比較枯燥,但是很有用!