本文源自本人的學習記錄整理與理解掸屡,其中參考閱讀了部分優(yōu)秀的博客和書籍,盡量以通俗簡單的語句轉述仅财。引用到的地方如有遺漏或未能一一列舉原文出處還望見諒與指出,另文章內容如有不妥之處還望指教盏求,萬分感謝 !
對于Class的結構的認識
class_rw_t
class_ro_t
class_ro_t中的baseMethodList是一維數組
method_t
method_t 是對方法/函數的封裝;我們每編寫一個方法最終都被封裝成了method_t這種結構荆烈;
簡化(去掉方法定義,保留屬性)過的源碼
struct method_t{
SEL name; //函數名/方法名
const char *types; //編碼(返回值類型憔购、參數類型)
IMP imp; //指向函數的指針(指針中存儲函數地址)
}
SEL 代表方法/函數名,一般叫做選擇器玫鸟,底層結構跟char*類似;
typedef struct objc_selector *SEL
可以通過@selector()和sel_registerName()獲得
可以通過selgetName()和NSStringFromSelector()轉成字符串
不同類中相同名字的方法,所對應的方法選擇器是相同的,地址值一樣妥曲;
SEL sel1 = sel-registerName("test")
SEL sel2 = @selector(test);
char *selStr = sel_getName(sel1);
NSString *selStr = NSStringFromSelector(sel2);
types 是包含了函數返回值、參數編碼的字符串檐盟;
如 :"v14@0:9"褂萧,字符串內容是用@encode(編碼技術)指令表示箱玷,可以將具體的類型表示成字符串編碼
示例注解:
v --> 返回值類型 14 所有參數所占字節(jié)數
@ --> 第一個參數 0代表從第0個字節(jié)開始,如果是8就表示從第8個字節(jié)開始
: --> SEL 類型 锡足、 _cmd
iOS中提供了一個叫做@encode
的指令壳坪,可以將具體的類型表示成字符串編碼
- @encode實際上是編譯器指令其中的一種
- @encode能夠返回一個Objective-C 類型編碼(Objective-C Type Encodings)
- @encode是一種編譯器內部表示的字符串舶得,方便識別,類似于 ANSI C 的 typeof 操作
在Objective-C中爽蝴,用@encode指令的方式來表示沐批,可以方便Runtime內部利用類型編碼幫助加快消息分發(fā)
常用的@encode指令:
IMP是指向函數的指針(存儲了所指向函數的地址),代表函數的具體實現
typedef id _Nullable (*IMP)(id _Nonnull, SEL _Nonnull,...);
- OC方法三要素是什么 蝎亚?
答:SEL (函數名/方法名) 九孩、types (編碼(返回值類型、參數類型))发框、IMP(指向函數的指針(函數地址))