古詩詞大全網 - 個性簽名 - 對象調用方法的詳細過程

對象調用方法的詳細過程

實例方法存在於類對象中。

類方法存在於元類中(元類實際上是壹個類對象)。

我們先來看類對象的結構布局。

我們看到壹個類對象是結構繼承,壹個對象結構。我們在以前的文章中分析了objc_object結構。這裏簡單說壹下objc_object,objc_object。objc _ object中有壹個ISA,它是壹個* * *對象。有壹種結構使用壹個位字段來存儲更多的信息。

超類是指向父類的指針。

緩存方法的緩存列表

比特& amp從FAST_DATA_MASK到class_rw_t的結構

在class_rw_t中,methods是方法的緩存類表。

我們之前討論分類的時候,也分析了method_array_t方法;結構

Methods是壹個二維數組,數組中的元素是分類的方法類表。

[

【分類方法1a方法,分類方法1b方法】,

[分類方法2a方法,分類方法2b方法]

]

當我們向壹個對象發送消息時,我們將找到方法數組並將其緩存在緩存中。即使我們調用壹個對象的父類的方法,它也會被緩存在緩存中的_buckets中。當我們在_buckets中緩存bucket_t時,_buckets會檢查是否需要擴展。如果需要展開,會清空所有元素。然後,它將被緩存。(這時候之前的緩存就沒了。)

我看到緩存結構中的_buckets是壹個數組,其中bucket_t structure _key是方法名_buckets相當於壹個離散列表(類似於字典)。

X0,接收方消息receiver存儲在寄存器中。

B.le LNilOrTagged //如果接收端為零,則跳轉到LNilOrTagged。

b.eq LReturnZero // nil check

Ret(返回)

如果對象為零,則返回。

如果對象不為空,則轉到CacheLookup並在緩存中查找它。

CacheHit命中緩存,結果是直接調用方法或者返回imp指針。

在緩存中找不到CheckMiss。

因為CacheLookup NORMAL傳遞的值是正常的,所以這裏我們暫時只分析__objc_msgSend_uncached。

我們再次分析MethodTableLookup,發現它是壹個宏。

BL _ _ class _ LookupMethodAndLoadCache 3表示跳轉到_ _ class _ LookupMethodAndLoadCache 3的方法。

然後我們來到lookUpImpOrForward。

我們來分析_class_resolveMethod。

如果是實例方法,會調用_class_resolveInstanceMethod。

我們來分析壹下_ class _ resolveInstanceMethod SEL _ resolveInstanceMethod is+(bool)resolveInstanceMethod:(SEL)SEL通過objc_msgSend調用這個類方法,我們可以重寫這個類方法,並動態地給類方法添加方法。

如果動態分析沒有做的事情,就會來到消息forwarding _ objc _ msg forward _ imp cache,這個消息是我們在匯編中找到的,但是分析後沒有源代碼,這裏暫時不分析匯編。

下面列出了幾種動態轉發的方法。

在消息轉發階段,如果未實現-forwardingTargetForSelector,將調用-methodSignatureForSelector方法返回方法簽名本身。

然後調用-forwardInvocation返回壹個NSInvocation對象。

另外,如果消息是消息轉發階段的類方法,+ForwardingTargetForSelector,+MethodSignatureForSelector將被調用。

,+forwardInvocation(雖然沒有公開api)

在消息轉發階段無論是類方法還是對象方法,實際上都是消息接收方調用上述方法。(這樣妳就能理解為什麽對象方法調用了——類方法調用+是因為消息接收方不同。)

1消息發送

2動態方法分析

3消息轉發