Runtime(消息機制)筆記

Runtime學習筆記,一個簡單的例子來演示下Runtime消息機制

Demo鏈接

  • 創建一個控制檯應用,在main.m中
int main(int argc, const char * argv[]) {
    @autoreleasepool {   
        id objc = [NSObject alloc];
        objc = [objc init];
    }
    return 0;
}
  • 打開控制檯,cd到main.m文件所在文件夾,輸入 clang -rewrite-objc main.m,然後你發現在文件夾中會多出一個main.cpp的c++文件。

  • 打開main.cpp文件,wtf?!上十萬行代碼……cmd+F搜索@autoreleasepool,你會找到最開始寫的那段代碼的底層實現代碼

int main(int argc, const char * argv[]) {
    /* @autoreleasepool */ { __AtAutoreleasePool __autoreleasepool; 

        id objc = ((NSObject *(*)(id, SEL))(void *)objc_msgSend)((id)objc_getClass("NSObject"), sel_registerName("alloc"));
        objc = ((id (*)(id, SEL))(void *)objc_msgSend)((id)objc, sel_registerName("init"));

    }
    return 0;
}
  • 去掉所有強制轉換,下面的代碼是不是看起來就很熟悉了呢?
id objc = objc_msgSend(objc_getClass("NSObject"),sel_registerName("alloc"));

objc    = objc_msgSend(objc,sel_registerName("init"));

利用Runtime消息機制,我們可以訪問別人寫的一些私有方法,而不去改變別人的代碼(私自改變別人的代碼是要喫砍刀的,切記,切記)

  • 創建一個Person對象,開放一個方法- eat,創建一個私有方法- count:
//Person.h
#import <Foundation/Foundation.h>

@interface Person : NSObject

-(void)eat;

@end


//Person.m
#import "Person.h"

@implementation Person

-(void)eat{
    NSLog(@"喫東西");
}

-(void)count:(int)num{
    NSLog(@"count:%d",num);
}

@end

//ViewController.m
#import "ViewController.h"
#import "Person.h"
#import <objc/message.h>

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    Person *p = objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"));
    p = objc_msgSend(p, sel_registerName("init"));

    objc_msgSend(p, sel_registerName("eat"));

    //在這裏,count:方法是私有的。對於有參的方法,在後面按照順序逗號隔開寫參數就好。
    objc_msgSend(p, sel_registerName("count:"),3);
}

-(void)test{
    //1.導入<objc/message.h>
    //2.在Build Settings 中搜索msg,設置爲NO
    //3.使用runtime
    id objc = objc_msgSend([NSObject class], @selector(alloc));
    objc = objc_msgSend(objc, @selector(init));
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

Runtime消息機制運行效果圖

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章