runtime

一個對象的方法像這樣[obj foo],編譯器轉成消息發送objc_msgSend(obj, foo),objec_msgSend的方法定義以下:函數

OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)spa

  1. 系統首先找到消息的接收對象,而後經過對象的isa找到它的類。
  2. 在它的類中查找method_list,是否有selector方法。
  3. 沒有則查找父類的method_list
  4. 找到對應的method,執行它的IMP
  5. 轉發IMPreturn值。

咱們看看對象(object),類(class),方法(method)這幾個的結構體:指針

//對象
struct objc_object {
  Class isa OBJC_ISA_AVAILABILITY;//isa指針指向類對象,
};
//類
struct objc_class {
  Class isa OBJC_ISA_AVAILABILITY;//isa指針指向的結構體建立,類對象的isa指針指向的咱們稱之爲元類(metaclass),元類的isa指針又指向了本身。
  #if !__OBJC2__
  Class super_class OBJC2_UNAVAILABLE;//super_class指針指向了父類的類對象,
  const char *name OBJC2_UNAVAILABLE;
  long version OBJC2_UNAVAILABLE;
  long info OBJC2_UNAVAILABLE;
  long instance_size OBJC2_UNAVAILABLE;
  struct objc_ivar_list *ivars OBJC2_UNAVAILABLE;
  struct objc_method_list **methodLists OBJC2_UNAVAILABLE;
  struct objc_cache *cache OBJC2_UNAVAILABLE;
  struct objc_protocol_list *protocols OBJC2_UNAVAILABLE;
  #endif
}
OBJC2_UNAVAILABLE;
//方法列表 struct objc_method_list {
  struct objc_method_list *obsolete OBJC2_UNAVAILABLE;
  int method_count OBJC2_UNAVAILABLE;
  #ifdef __LP64__
  int space OBJC2_UNAVAILABLE;
  #endif
  /* variable length structure */
  struct objc_method method_list[1] OBJC2_UNAVAILABLE;
}
OBJC2_UNAVAILABLE;
//方法
struct objc_method {
  SEL method_name OBJC2_UNAVAILABLE;
  char *method_types OBJC2_UNAVAILABLE;
  IMP method_imp OBJC2_UNAVAILABLE;
}
 
 
SEL originalSelector = @selector(viewDidLoad);
Method originalMethod = class_getInstanceMethod(class,originalSelector);
class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
method_exchangeImplementations(originalMethod, swizzledMethod);
class_getMethodImplementation(objc_getMetaClass("A"),SEL name);//獲取類方法的實現
class_getMethodImplementation(objc_getClass("A"),SEL name);//獲取實例方法的實現
Method class_getClassMethod(Class cls, SEL name);//獲取類方法的方法體
Method class_getInstanceMethod(Class cls, SEL name);//獲取實例方法的方法體
IMP method_getImplementation(Method m);//根據方法體獲取IMP地址

IMP method_getImplementation(Method m);//根據方法體
 
 
Method和咱們平時理解的函數是一致的,就是表示可以獨立完成一個功能的一段代碼,
其實 selector就是個映射到方法的 C字符串,你能夠用  Objective-C 編譯器命令 @selector()或者  Runtime 系統的 sel_registerName函數來得到一個  SEL 類型的方法選擇器。



的定義就是指向最終實現程序的內存地址的指針。

消息轉發完整流程:
_objc_msgForward(id receiver,SEL sel, ...) 調用此方法進行消息轉發,即便實現了該方法也會轉發typedef id (*IMP)(id, SEL, ...); IMP
 
super 關鍵字接收到消息時,編譯器會建立一個  objc_super 結構體:


struct objc_super { id receiver; Class class; };
這個結構體指明瞭消息應該被傳遞給特定的父類。  receiver 仍然是  self 自己,當咱們想經過  [super class] 獲取父類時,編譯器實際上是將指向  self 的  id 指針和  class 的 SEL 傳遞給了  objc_msgSendSuper 函數。只有在  NSObject 類中才能找到  class 方法,而後  class 方法底層被轉換爲  object_getClass(), 接着底層編譯器將代碼轉換爲  objc_msgSend(objc_super->receiver, @selector(class)),傳入的第一個參數是指向  self 的  id 指針,與調用  [self class] 相同,因此咱們獲得的永遠都是  self 的類型。
相關文章
相關標籤/搜索