1. 程式人生 > >ios runtime IMP指標 訊息轉發機制

ios runtime IMP指標 訊息轉發機制

本文程式碼是根據訊息轉發機制來寫的, 有不妥之處, 請大神指正

1. UIViewController (ViewDidLoadName)檔案 UIViewController的category

在實現viewDidLoad系統方法的前提下 新增自定義的方法

2. Person類有一個run的方法(沒有實現),這裡展示了OC中的訊息轉發機制, 使其不崩潰並實現方法,或者轉到Car的run方法來實現

直接上程式碼(註釋很全, 簡單易懂)

ViewController.m檔案

  1. <span style="font-size:18px;"
    >//  ViewController.m
  2. //  MethodSwizzlingIMPdemo
  3. //
  4. //  Created by 帝炎魔 on 16/5/12.
  5. //  Copyright © 2016年 帝炎魔. All rights reserved.
  6. //
  7. #import "ViewController.h"
  8. #import "UIViewController+ViewDidLoadName.h"
  9. #import "Person.h"
  10. @interface ViewController ()  
  11. @end
  12. @implementation ViewController  
  13. - (void
    )viewDidLoad {  
  14.     [super viewDidLoad];  
  15.     // 建立Person物件 執行run方法, 但是Person類中並沒有實現run方法
  16.     // 我們利用訊息轉發機制防止其崩潰,或者用其他方法來代替[per run]的方法
  17.     Person *per = [[Person alloc] init];  
  18.     [per run];  
  19.     // Do any additional setup after loading the view, typically from a nib.
  20. }  
  21. - (void)didReceiveMemoryWarning {  
  22.     [super didReceiveMemoryWarning];  
  23.     // Dispose of any resources that can be recreated.
  24. }  
  25. @end</span>  

UIViewController (ViewDidLoadName).h檔案

  1. <span style="font-size:18px;">//  UIViewController+ViewDidLoadName.h
  2. //  MethodSwizzlingIMPdemo
  3. //
  4. //  Created by 帝炎魔 on 16/5/12.
  5. //  Copyright © 2016年 帝炎魔. All rights reserved.
  6. //
  7. #import <UIKit/UIKit.h>
  8. @interface UIViewController (ViewDidLoadName)  
  9. @end</span>  
UIViewController (ViewDidLoadName).m檔案
  1. <span style="font-size:18px;">//  UIViewController+ViewDidLoadName.m
  2. //  MethodSwizzlingIMPdemo
  3. //
  4. //  Created by 帝炎魔 on 16/5/12.
  5. //  Copyright © 2016年 帝炎魔. All rights reserved.
  6. //
  7. #import "UIViewController+ViewDidLoadName.h"
  8. #import <objc/runtime.h>
  9. // 有返回值的IMP
  10. typedefid (* _IMP) (idSEL, ...);  
  11. // 沒有返回值的IMP(定義為VIMP)
  12. typedefvoid (* _VIMP) (idSEL, ...);  
  13. @implementation UIViewController (ViewDidLoadName)  
  14. +(void)load  
  15. {  
  16.     // 保證交換方法只執行一次
  17.     static dispatch_once_t onceToken;  
  18.     dispatch_once(&onceToken, ^{  
  19.         // 獲取原始方法
  20.         Method viewDidLoad = class_getInstanceMethod(self@selector(viewDidLoad));  
  21.         // 獲取原始方法的實現指標(IMP)
  22.         _VIMP viewDidLoad_IMP = (_VIMP)method_getImplementation(viewDidLoad);  
  23.         // 重新設定方法的實現
  24.         method_setImplementation(viewDidLoad, imp_implementationWithBlock(^(id target, SEL action) {  
  25.             // 呼叫系統的原生方法
  26.             viewDidLoad_IMP(target, @selector(viewDidLoad));  
  27.             // 新增的功能程式碼
  28.             NSLog(@"%@ did load", target);  
  29.         }));  
  30.     });  
  31. }  
  32. //+ (void)load
  33. //{
  34. //    // 保證交換方法只執行一次
  35. //    static dispatch_once_t onceToken;
  36. //    dispatch_once(&onceToken, ^{
  37. //        // 獲取到這個類的viewDidLoad方法, 它的型別是一個objc_method結構體的指標
  38. //        Method viewDidLoad = class_getInstanceMethod(self, @selector(viewDidLoad));
  39. //        
  40. //        // 獲取到自己剛剛建立的一個方法
  41. //        Method myViewDidLoad = class_getInstanceMethod(self, @selector(myViewDidLoad));
  42. //        
  43. //        // 交換兩個方法的實現
  44. //        method_exchangeImplementations(viewDidLoad, myViewDidLoad);
  45. //        
  46. //      
  47. //        
  48. //    });
  49. //}
  50. //
  51. //- (void)myViewDidLoad
  52. //{
  53. //    // 呼叫系統的方法
  54. //    [self myViewDidLoad];
  55. //    NSLog(@"%@ did load", self);
  56. //}
  57. @end</span>  

Person.h 檔案
  1. <span style="font-size:18px;">//  Person.h
  2. //  MethodSwizzlingIMPdemo
  3. //
  4. //  Created by 帝炎魔 on 16/5/12.
  5. //  Copyright © 2016年 帝炎魔. All rights reserved.
  6. //
  7. #import <Foundation/Foundation.h>
  8. @interface Person : NSObject  
  9. - (void)run;  
  10. @end</span>  

Person.m檔案
  1. <span style="font-size:18px;">//  Person.m
  2. //  MethodSwizzlingIMPdemo
  3. //
  4. //  Created by 帝炎魔 on 16/5/12.
  5. //  Copyright © 2016年 帝炎魔. All rights reserved.
  6. 相關推薦

    ios runtime IMP指標 訊息轉發機制

    本文程式碼是根據訊息轉發機制來寫的, 有不妥之處, 請大神指正 1. UIViewController (ViewDidLoadName)檔案 UIViewController的c

    iOS runtime探究(二): 從runtime開始深入理解OC訊息轉發機制

    你要知道的runtime都在這裡 本文主要講解runtime相關知識,從原理到實踐,由於包含內容過多分為以下五篇文章詳細講解,可自行選擇需要了解的方向: 本文是系列文章的第二篇文章從runtime開始: 深入理解OC訊息轉發機制,主要從runtime

    iOS 訊息轉發機制(附程式碼)

    在iOS中,如果遇到訊息無法處理。比如:通過- (id)performSelector:(SEL)aSelector;呼叫了一個方法但是沒有實現它。對它發生呼叫後,系統找不到執行該函式的地方。在系統發生cash之前,會先啟動訊息轉發機制。試圖對該訊息進行處理。動態訊息解析+

    iOS訊息轉發機制

    訊息轉發機制 假設說我們宣告一個類, 初始化物件, 並且在此類宣告一個方法, 呼叫方法的時候底層是怎麼處理的呢? 今天我們來簡單模擬測試, 來看道理髮生了什麼 以下是呼叫方法處理的方案圖, 按照方案順序去處理 以下是系統方法

    OC學習Runtime訊息傳遞,訊息轉發機制

    堅持 成長 每日一篇 相關類和函式 介紹訊息傳送機制之前介紹一下會用到的幾個相關類和函式 NSMethodSignature(方法簽名) 方法簽名:用語記錄一個方法的引數和返回值型別的類。類似於objc_method_description結構體。方

    Android--利用Handler訊息轉發機制實現倒計時(內含防止記憶體洩露處理)

    真正學會Handler必須要了解的相關概念 相關概念圖示: Message:儲存資訊的物件,被Handler線上程間轉發,實現執行緒間的通訊。 MessageQueue:以有序的方式排列的,等待處理的事件(Runnable或者Message)。

    oc訊息轉發機制

    Class 型別物件 OC本身是一種強型別語言,但其執行時功能讓它又有了動態語言的特點。OC中物件的型別和物件所執行的方法都是在執行時階段進行查詢並確認的,這種機制被稱為動態繫結。想要弄清楚執行時如何能夠實現動態繫結機制,首先要了解OC中物件的本質。 OC

    理解訊息傳遞機制訊息轉發機制

    訊息傳遞機制 在物件上傳遞方法叫做“傳遞訊息”(pass a message)。訊息有“名稱”(name)或“選擇子”(selector),可以接受引數,而且可能還有返回值。 在Object-c中,如果向物件傳遞訊息,那就會使用動態繫結機制來決定需要呼叫的方

    iOS runtime探究(二): 從runtime開始深入理解OC消息轉發機制

    phoenix face exp nslog void string ams ber 解釋 你要知道的runtime都在這裏 轉載請註明出處 http://blog

    iOS探索:Runtime訊息轉發及動態新增方法

    在開始之前,我們先來了解下OC中的類與物件 這是一張經典的類的關係示意圖,接下來簡單的介紹一下這張圖 首先當我們建立一個實力物件,會拷貝這個實力物件所屬類的成員變數,但是不會拷貝類定義的方法 當我們傳送訊息給例項物件時,會通過這個例項物件中的isa指標去找到它對應的類,在

    Objective-C runtime原始碼學習之IMP定址(不包括訊息轉發部分)

    寫在前面 前段時間寫了一篇部落格runtime如何通過selector找到對應的IMP地址?(分別考慮類方法和例項方法),這是在看《招聘一個靠譜的iOS》時回答第22題時總結的一篇部落格,不過這篇部落格中並沒有牽涉到底層的程式碼,而且也留下了幾個沒有解決的

    iOS Runtime 執行時之三:訊息處理機制

    前面我們討論了Runtime中對類和物件的處理,及對成員變數與屬性的處理。這一章,我們就要開始討論Runtime中最有意思的一部分:訊息處理機制。我們將詳細討論訊息的傳送及訊息的轉發。不過在討論訊息之前,我們先來了解一下與方法相關的一些內容。 基礎資料型別

    runtime總結二之訊息機制(包括訊息轉發訊息交換的黑魔法)

    runtime的訊息機制 前面提到過編譯器最終會把我們的訊息傳送轉化為函式呼叫 訊息傳送 [object sendMassage] 首先編譯器會在執行時將上面的例子轉化為objc_msgSend(obj,@selector(sendMassage))這個

    iOS runtime,訊息傳送

    Objective-C Runtime iOS執行時(Runtime)詳解+Demo iOS 訊息傳送與轉發詳解 [iOS] runtime 的使用場景--實戰篇   runtime 應用: Method Swizzling OC 實現: iOS runtime

    OC的訊息傳送以及轉發機制

    SEL:Objective-C在編譯時,會依據每一個方法的名字、引數序列,生成一個唯一的整型標識(Int型別的地址),這個標識就是SEL.本質上,SEL只是一個指向方法的指標. Method:Method = SEL + IMP + method_types,相當於在SEL和IMP之間建立

    iOS —— RunTime詳解(傳送訊息)一

    一、RunTime簡介 RunTime簡稱執行時。OC就是執行時機制,也就是在執行時候的一些機制,其中最主要的是訊息機制。 對於C語言,函式的呼叫在編譯的時候會決定呼叫哪個函式。 對於OC語言,屬於動態呼叫過程,在編譯的時候並不能決定真正呼叫哪個函式,只有在真正

    iOS runtime機制和使用

    runtime簡稱執行時。OC是執行時機制,也就是在執行時才做一些處理。例如:C語言在編譯的時候就知道要呼叫哪個方法函式,而OC在編譯的時候並不知道要呼叫哪個方法函式,只有在執行的時候才知道呼叫的方法函式名稱,來找到對應的方法函式進行呼叫。 匯入 想要使用runtime,

    【精】iOS知識樹,知識點(包括物件、Block、訊息轉發、GCD、執行時、runloop、動畫、Push、KVO、tableview,UIViewController、提交AppStore)

            本文旨在總結iOS知識網路,知識點,該知識網路羅列出常見UIKit、Foundation的物件特點和一些使用經驗,可以看成是一本書;文字編輯採用樹的形式,對知識點進行羅列,並標註一些使用經驗(★)希望對初學者有用或給一些解決疑難雜症者提供思路;某些知識點會深入

    iOS 通知中心 NSNotificationCenter(訊息機制)

    今天專案要用到NSNotificationCenter,我喜歡叫它訊息(有的地方叫通知)。前兩天有弄過訊息推送,所以想對不瞭解的人解釋一下,ios訊息推送與這個訊息不是一回事!(我感覺他倆名字有的相似,怕有人誤會) 因為本人菜鳥一枚,所以之前弄過一次這個。但是今天要用的時候

    IOS NSNotificationCenter訊息通訊機制介紹

    訊息傳送機構:舉例說明 在有需要的類中,傳送訊息 //傳送訊息出去,這裡的物件是一個數組:saveImageArray [[NSNotificationCenter defaultCenter] postNotificationName:@"postData" object:saveImageArray];