[Runtime]-動態添加方法

 有沒有使用過performSelector,
 使用過
 
 何時使用?
 動態添加方法的時候使用過
 
 怎麼動態添加方法?
 使用runtime
 
 爲何要動態添加方法?
 OC都是懶加載機制,只要一個方法實現了,就會立刻添加到方法列表上.方法中有不少映射關係,這無形中就會消耗了內存
 好比一個app:有免費版、收費版
 好比:QQ、微博、直播等等應用,都有會員機制,這樣咱們能夠動態添加方法1ios

Runtime (動態添加方法):xcode

若是咱們建立一個Person類,而後在viewDidLoad中建立該對象,咱們使用performSelector去調用一個Person類中沒有的方法,結果系統報錯找不到方法:app

  • Person *p = [[Person alloc]init];
        // 執行某個方法
        [p performSelector:@selector(eat)];
  • #import <Foundation/Foundation.h>
    
    @interface Person : NSObject
    
    @end
    
    
    #import "Person.h"
    #import <objc/message.h>
    
    @implementation Person
    
    @end

這時候咱們能夠動態去添加方法:ide

  1. 首先:咱們在Person 類中去實現一個方法:
  • // 任何方法默認都有兩個隱式參數,self,_cmd
    // 做用:動態添加方法、或者處理一些未實現的方法
    // 何時調用?只要一個對象調用了一個未實現的方法,就會調用這個方法來進行處理
    + (BOOL)resolveInstanceMethod:(SEL)sel {
        
        //NSLog(@"%@",NSStringFromSelector(sel));
        //[NSStringFromSelector(sel) isEqualToString:@"eat"]
        
        if (sel == NSSelectorFromString(@"eat")) {
            // class:第一個參數:給那個類添加方法
            // SEL:添加哪一個方法
            // IMP:implementation:方法=>函數=>函數的入口=>函數名
            // type:方法的類型
            class_addMethod(self, sel, (IMP)funcA, "v@:");
            
            return YES;
        }
        
        return [super resolveInstanceMethod:sel];
    }

      2.主要是這個方法的參數咱們要掌握:class_addMethod(self, sel, (IMP)funcA, "v@:");函數

查看參數文檔地址:xcode-->window-->Documentation and API Reference-->展開ios9.3-->Languages &     Utilities-->Objective-C-->Guides-->Objective-C Runtime Programming Guide-->Dynamic Method Resolution + Type Encodingsui

 Runtime中文文檔地址連接: http://blog.csdn.net/liangliang103377/article/details/39007683    spa

  • // 聲明一個函數
    void funcA(id self,SEL _cmd) {
        NSLog(@"吃東西");
    }
  • 最後打印:吃東西











若是咱們是動態建立一個帶有參數的方法.net

  • #import "Person.h"
    #import <objc/message.h>
    
    @implementation Person
    
    // 聲明一個函數
    void funcA(id self,SEL _cmd,NSNumber *metre) {
        NSLog(@"跑了%@米",metre);
    }
    
    + (BOOL)resolveInstanceMethod:(SEL)sel {
        
        //NSLog(@"%@",NSStringFromSelector(sel));
        
        //[NSStringFromSelector(sel) isEqualToString:@"eat"]
        if (sel == NSSelectorFromString(@"run:")) {
            // class:第一個參數:給那個類添加方法
            // SEL:添加哪一個方法
            // IMP:implementation:方法=>函數=>函數的入口=>函數名
            // type:方法的類型
            class_addMethod(self, sel, (IMP)funcA, "v@:@");
            
            return YES;
        }
        
        return [super resolveInstanceMethod:sel];
    }
    
    @end

方法的調用:code

  • - (void)viewDidLoad {
        [super viewDidLoad];
        
        // _cmd:當前方法方法編號
        NSLog(@"%@",NSStringFromSelector(_cmd));
        
        Person *p = [[Person alloc]init];
        // 執行某個方法
        [p performSelector:@selector(run:) withObject:@100];
        
    }

最後打印:跑了100米orm

 

知識點

  1. 1:任何方法默認都有兩個隱式參數:self、_cmd
  1. 2:_cmd:當前方法方法編號
  2. 在ViewDidLoad中打印該參數:
  3. NSLog(@"%@",NSStringFromSelector(_cmd));

  3:+ (BOOL)resolveInstanceMethod:(SEL)sel  ?做用?何時調用?

    >何時調用?只要一個對象調用了一個未實現的方法,就會調用這個方法來進行處理
    >做用?動態添加方法、或者處理一些未實現的方法

  

意見反饋郵件:1415429879@qq.com 歡迎大家的閱讀和讚揚、謝謝!

相關文章
相關標籤/搜索