1. 程式人生 > >iOS —— RunTime詳解(動態新增方法)三

iOS —— RunTime詳解(動態新增方法)三

一、動態新增方法

開發使用場景:如果一個類方法非常多,載入類到記憶體的時候也比較耗費資源,需要給每個方法生成對映表,可以使用動態給某個類,新增方法解決。

經典面試試題:有沒有使用performSelector.其實主要想問你有沒有動態新增過方法。

+ (BOOL)resolveInstanceMethod:(SEL)sel:當物件呼叫了沒有實現的方法沒有實現就會呼叫resolveInstanceMethod。

resolveInstanceMethod作用:知道哪些方法沒有實現,從而動態新增方法

sel:沒有實現的方法

//動態新增的方法:

引數一:cls:給哪個類新增方法

引數二:SEL 新增方法的方法編號是什麼

引數三:IMP:方法實現,函式入口,函式名

class_addMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,

                const char * _Nullable types)

Persion.m

#import "Persion.h"
#import <objc/message.h>
@implementation Persion


+(BOOL)resolveInstanceMethod:(SEL)sel
{
    //NSLog(@"%@",NSStringFromSelector(sel));
    //動態新增eat方法
    if (sel == @selector(eat))  {
        
        /*
         引數一:cls: 給哪個類新增方法
         引數二:SEL: 新增方法的方法編號是什麼
         引數三:IMP:方法實現,函式入口,函式名
         引數四:types:方法型別
         
         */
        //動態新增方法
        class_addMethod(self, sel, (IMP)eat, "
[email protected]
:"); return YES; } //新增新增跑的方法 else if (sel == @selector(run:)) { class_addMethod(self, sel, (IMP)run, "[email protected]:@"); return YES; } return [super resolveInstanceMethod:sel]; } #pragma mark- 下面的是C語言的函式 /* 預設一個方法都有兩個引數,self,_cmd,隱式引數 self:方法呼叫者 _cmd:呼叫方法的編號 */ // 定義的函式 void eat(id self,SEL _cmd) { NSLog(@"動態新增的方法1=%@ %@",self,NSStringFromSelector(_cmd)); } //定義的函式run void run(id self,SEL _cmd,id number) { NSLog(@"動態新增跑步=%@",number); }

Viewcontroller

#import "ViewController.h"
#import "Persion.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    Persion *p=[[Persion alloc]init];
    
    [p performSelector:@selector(eat)];
    
    //帶引數
    [p performSelector:@selector(run:) withObject:@30];
    
    
}