關于runtime的一些簡單理解

1.消息發送
OC:運行時機制,消息機制是運行時機制最重要的機制
消息機制:任何方法調用,本質都是發送消息

SEL:方法編號,根據方法編號就可以找到對應方法實現
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat)];
// 讓p發送消息
// objc_msgSend(p, @selector(eat));
// objc_msgSend(p, @selector(run:),10);帶參數的消息
這是消息發送的對象方法。

// 獲取類對象
Class personClass = [Person class];
[personClass performSelector:@selector(eat)];
// 運行時
objc_msgSend(personClass, @selector(eat));
這是消息發送的類方法。

2.方法交換
// 交換方法實現,方法都是定義在類里面
// class_getMethodImplementation:獲取方法實現
// class_getInstanceMethod:獲取對象
// class_getClassMethod:獲取類方法
// IMP:方法實現

// Class:獲取哪個類方法
// SEL:獲取方法編號,根據SEL就能去對應的類找方法
Method imageNameMethod = class_getClassMethod([UIImage class], @selector(imageNamed:));

// xmg_imageNamed
Method xmg_imageNamedMethod = class_getClassMethod([UIImage class], @selector(xmg_imageNamed:));

// 交換方法實現
method_exchangeImplementations(imageNameMethod, xmg_imageNamedMethod);

實列:

  • (UIImage *)xmg_imageNamed:(NSString *)imageName
    {
    // 1.加載圖片
    UIImage *image = [UIImage xmg_imageNamed:imageName];

    // 2.判斷功能
    if (image == nil) {
    NSLog(@"加載image為空");
    }

    return image;
    }
    這樣就實現了兩個方法的交換。

3.動態添加方法
// performSelector:動態添加方法,聲明一個類,并不提供eat:這個方法
Person *p = [[Person alloc] init];
[p performSelector:@selector(eat:) withObject:@111];
在Person類中,
// 動態添加方法,首先實現這個resolveInstanceMethod
// resolveInstanceMethod調用:當調用了沒有實現的方法沒有實現就會調用resolveInstanceMethod
// resolveInstanceMethod作用:就知道哪些方法沒有實現,從而動態添加方法
// sel:沒有實現方法

  • (BOOL)resolveInstanceMethod:(SEL)sel
    {
    // NSLog(@"%@",NSStringFromSelector(sel));

    // 動態添加eat方法
    if (sel == @selector(eat:)) {

      /*
       cls:給哪個類添加方法
       SEL:添加方法的方法編號是什么
       IMP:方法實現,函數入口,函數名
       types:方法類型
       */
      // @:對象 :SEL
      class_addMethod(self, sel, (IMP)aaaa, "v@:@");
      // 處理完
      return YES;
    

    }
    return [super resolveInstanceMethod:sel];
    }

聲明一個C語言的函數來動態添加
void aaaa(id self, SEL _cmd, id param1)
{
NSLog(@"調用eat %@ %@ %@",self,NSStringFromSelector(_cmd),param1);
}

4.分類動態添加屬性
列如給NSObject添加一個name屬性

  • (void)setName:(NSString *)name
    {
    // 添加屬性,跟對象
    // 給某個對象產生關聯,添加屬性
    // object:給哪個對象添加屬性
    // key:屬性名,根據key去獲取關聯的對象 ,void * == id
    // value:關聯的值
    // policy:策越
    objc_setAssociatedObject(self, @"name", name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    // _name = name;
    }

  • (NSString *)name
    {
    return objc_getAssociatedObject(self, @"name");
    }

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉至元數據結尾創建: 董瀟偉,最新修改于: 十二月 23, 2016 轉至元數據起始第一章:isa和Class一....
    40c0490e5268閱讀 1,774評論 0 9
  • 對于從事 iOS 開發人員來說,所有的人都會答出【runtime 是運行時】什么情況下用runtime?大部分人能...
    夢夜繁星閱讀 3,732評論 7 64
  • 我們常常會聽說 Objective-C 是一門動態語言,那么這個「動態」表現在哪呢?我想最主要的表現就是 Obje...
    Ethan_Struggle閱讀 2,231評論 0 7
  • Runtime是一套比較底層的純C語言API,包含了很多底層的C語言API。在我們平時編寫的OC代碼中,程序運行時...
    這個年紀的情愫丶閱讀 627評論 5 3
  • 清明那天,下起了細雨。綿綿的雨織成了網,鋪灑大地。 這是在山間的小道,野草密布。順著這條路往前走,便能看到一個遠處...
    叫我陳哥閱讀 241評論 0 0