iOS Sharing #02 | 2019-03-30

Adrenine發表於2019-03-22

目錄

1、類方法去哪裡找?

2、isa指標有幾種型別麼?

3、分類的方法具體是在什麼時候新增到類的方法列表中?

4、class_addMethod()都需要什麼引數?

5、iOS訊息轉發流程


1、類方法去哪裡找?

答: 見上一期《iOS Sharing #01 | 2019-03-23》第5問

5、例項方法去哪裡找?


2、isa指標有幾種型別麼?

答: isa指標分,指標型別和非指標型別,32位只做地址儲存,非嵌入式64位架構下,包含除類地址外的其他資訊。

isa指標型別


3、分類的方法具體是在什麼時候新增到類的方法列表中?

答: 類在編譯後會以 class_ro_t 的結構把類的資訊儲存在 bits 裡,執行時的 realizeClass 之後,會把 ro 中的所有資訊拷貝到 bits 的 data 內,即以 class_rw_t 的形式存在,分類裡的方法即在這個時候新增到類的方法表裡,並在方法表陣列的最前面

4、class_addMethod()都需要什麼引數?

答:
/**
* Adds a new method to a class with a given name and implementation.
*
* @param cls The class to which to add a method.
* @param name A selector that specifies the name of the method being added.
* @param imp A function which is the implementation of the new method. The function must take at least two arguments—self and _cmd.
* @param types An array of characters that describe the types of the arguments to the method.
*
* @return YES if the method was added successfully, otherwise NO
* (for example, the class already contains a method implementation with that name).
*
* @note class_addMethod will add an override of a superclass's implementation,
* but will not replace an existing implementation in this class.
* To change an existing implementation, use method_setImplementation.
*/
OBJC_EXPORT BOOL class_addMethod(Class cls, SEL name, IMP imp,
const char *types)
__OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_2_0);

複製程式碼
  • 給類新增一個新的方法和該方法的具體實現
  • BOOL: 返回值,YES -------方法新增成功 NO --------方法新增失敗
  • Class cls: 將要給新增方法的類,傳的型別 [類名 class]
  • SEL name: 將要新增的方法名,傳的型別 @selector(方法名)
  • IMP imp:實現這個方法的函式 ,傳的型別
    • 1、C語言寫法:(IMP)方法名
    • 2、OC的寫法:class_getMethodImplementation(self,@selector(方法名:))
  • const char *types:表示我們要新增的方法的返回值和引數
  • "v@:@":
    • 'v'是新增方法無返回值
    • '@'表示是id(也就是要新增的類)
    • ':'表示新增的方法型別
    • '@'表示引數型別

const char *types含義表:

Code Meaning
c A char
i An int
s A short
l A long l is treated as a 32-bit quantity on 64-bit programs.
q A long long
C An unsigned char
I An unsigned int
S An unsigned short
L An unsigned long
Q An unsigned long long
f A float
d A double
B A C++ bool or a C99 _Bool
v A void
* A character string (char *)
@ An object (whether statically typed or typed id)
# A class object (Class)
: A method selector (SEL)
[array type] An array
{name=type...} A structure
(name=type...) A union
bnum A bit field of num bits
^type A pointer to type
? An unknown type (among other things, this code is used for function pointers)

注意:
用這個方法新增的方法是無法直接呼叫的,必須用performSelector:呼叫。 因為performSelector是執行時系統負責去找方法的,在編譯時候不做任何校驗;如果直接呼叫編譯是會自動校驗。 新增方法是在執行時新增的,你在編譯的時候還沒有這個本類方法,所以當然不行。


5、iOS訊息轉發流程

答:
訊息轉發機制基本分為三個步驟:
  • 1、動態方法解析
  • 2、備用接受者
  • 3、完整轉發

程式碼

流程

類方法:

類方法

例項方法:

例項方法

詳細流程:

詳細流程

感謝大佬提供的圖片。


倉庫

本篇相關程式碼


聯絡方式

郵箱: adrenine@163.com

郵箱: holaux@gmail.com

郵箱: ledahapple@icloud.com

相關文章