Runtime(一) 初識runtime

iOS開發中的runtime被稱爲黑魔法,本節就向大家講解什麼是runtime.

runtime 是屬於OC底層的實現,可以進行一些OC無法操作的事情
1.利用Runtime,在程序運行時,動態加載一個類
2.利用Runtime,在程序運行時,動態修改類的屬性,方法
3.利用Runtime遍歷一個類的所有屬性
……(總之很強大)

接下來我會一步一步展示下什麼是runtime,

一、首先配置下測試環境

首先我們新建一個工程,X-code5.0之後蘋果不建議使用底層代碼,如果使用runtime方法,需要在buildSetting中做修改。如下所示:將objc_msgSend檢測設爲禁用。

這裏寫圖片描述

接着我們新建一個Person類,聲明並實現eat方法:

這裏寫圖片描述

二、我們先看下傳統的方法調用都有哪些:

我們可以使用傳統的方法調用如下,相信大家都經常用到

  Person *person = [[Person alloc] init];

    // 1.OC語法的方法調用。
    [person eat];

    // 2.用performSelector調用
    [person performSelector:@selector(eat)];

三、接下來我們使用runtime來調用

引入頭文件:#import < objc/message.h> 或 #include < objc/runtime.h> 前者包括後者。

    Person *person = [[Person alloc] init];    

    // 3.使用runtime調用
    objc_msgSend(person, @selector(eat));

同樣打印信息如下:

2017-04-21 14:34:28.891 Runtime[38675:3227119] enter person eat

我們詳解下:

objc_msgSend(<#id self#>, <#SEL op, ...#>)

我們OC的方法調用的消息發送機制可以在這裏得到答案,每一個方法,其實都是對一個對象發送一個消息。
id self : 發送消息的對象。
<#SEL op, …#>:發送什麼消息,後面…就代表可擴展參數,如果方法需要入參的話可做擴展,就像NSLog(<#NSString * _Nonnull format, …#>)擴展參數用法一樣。

另外:@selector方法選擇器在runtime時被替換成:sel_registerName

所以方法進一步底層化爲:

objc_msgSend(person, sel_registerName("init"))

四、msgSend還可以做哪些事?

上面一個簡單的展示,可以用這個方法來代替方法調用,支持方法有多個入參,那麼

Person *person = [[Person alloc] init]

可以使用類似方法嗎?答案是可以的。
我們一步一步拆分得到:
1、

Person *person = [Person alloc];

我們可以使用runtime的另一個objc_getClass(“Person”),得到類的名字,再調用alloc:

objc_msgSend(objc_getClass("Person"), @selector(alloc))

2、

[person init];

我們可以直接這樣做:
objc_msgSend(person, @selector(“init”));

總結整理後我們可以吧person的初始化方法替換爲runtime語言:

objc_msgSend(objc_getClass("Person"), sel_registerName("alloc"),sel_registerName("init"));

五、編譯文件,查看真實的runtime

讀者可能會問:我該怎麼證明這些都是正確的呢?相信看完下面就明白了。

1、我們新建一個Command Line工程,注意一定要是這樣的工程,因爲這裏不會因人UIKit框架,筆者能力有限,暫不會編譯那種文件。

2、新建一個Person類,同樣聲明實現eat方法:

這裏寫圖片描述

3、我們在控制檯用clang指令編譯main.m文件:

這裏寫圖片描述

4、在同級目錄生成了個main.cpp文件,這個就是我們想要的:

這裏寫圖片描述

5、打開main.cpp我們看文件的最下邊:

這裏寫圖片描述

怎麼樣,相信了吧,我們的每個方法在編譯時候都會被編譯成runtime運行時語言,他能幫助我們做很多強大功能。

接下來在後面博客中,我會使用實際案例,幫助大家更深刻的理解runtime。

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