在最開始聽到runtime的時候,我是感到恐懼的,多麼高大上的東西啊!!!後來,開始在網上查一些資料,可是就是隻有那麼幾篇,看了好久,還不知所云,所以就更加恐懼了!!!!後來經過查看documents 以及一些國外大牛的blogs,終於對runtime有了更深刻的瞭解!於是就想寫下這些東西,希望對讀者們有幫助……
runtime實現的機制是什麼,怎麼用,一般用於幹嘛?
這個問題我就不跟大家繞彎子了,直接告訴大家,
runtime是一套比較底層的純C語言API, 屬於1個C語言庫, 包含了很多底層的C語言API。
在我們平時編寫的OC代碼中, 程序運行過程時, 其實最終都是轉成了runtime的C語言代碼, runtime算是OC的幕後工作者
比如說,下面一個創建對象的方法中,
舉例:
OC :
[[MJPerson alloc] init]
runtime :
objc_msgSend(objc_msgSend(“MJPerson” , “alloc”), “init”)
第二個問題
runtime 用來幹什麼呢??用在那些地方呢?怎麼用呢?
runtime是屬於OC的底層, 可以進行一些非常底層的操作(用OC是無法現實的, 不好實現)
在程序運行過程中, 動態創建一個類(比如KVO的底層實現)
在程序運行過程中, 動態地爲某個類添加屬性\方法, 修改屬性值\方法
遍歷一個類的所有成員變量(屬性)\所有方法
例如:我們需要對一個類的屬性進行歸檔解檔的時候屬性特別的多,這時候,我們就會寫很多對應的代碼,但是如果使用了runtime就可以動態設置!
例如,PYPerson.h的文件如下所示import
@interface PYPerson : NSObject
@property (nonatomic, assign) int age;
@property (nonatomic, assign) int height;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, assign) int age2;
@property (nonatomic, assign) int height2;
@property (nonatomic, assign) int age3;
@property (nonatomic, assign) int height3;
@property (nonatomic, assign) int age4;
@property (nonatomic, assign) int height4;
而PYPerson.m實現文件的內容如下
<!-- lang: cpp -->#import "PYPerson.h"
import
@implementation PYPerson
(void)encodeWithCoder:(NSCoder )encoder
{
unsigned int count = 0;
Ivar ivars = class_copyIvarList([PYPerson class], &count);for (int i = 0; i<count; i++) {
// 取出i位置對應的成員變量Ivar ivar = ivars[i];// 查看成員變量const char *name = ivar_getName(ivar);// 歸檔NSString *key = [NSString stringWithUTF8String:name];id value = [self valueForKey:key]; [encoder encodeObject:value forKey:key];
}
free(ivars);
}(id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {unsigned int count = 0; Ivar *ivars = class_copyIvarList([PYPerson class], &count);for (int i = 0; i<count; i++) { // 取出i位置對應的成員變量 Ivar ivar = ivars[i]; // 查看成員變量 const char *name = ivar_getName(ivar); // 歸檔 NSString *key = [NSString stringWithUTF8String:name]; id value = [decoder decodeObjectForKey:key]; // 設置到成員變量身上 [self setValue:value forKey:key]; } free(ivars);
}
return self;
}
這樣我們可以看到歸檔和解檔的案例其實是runtime寫下的
學習,runtime機制首先要了解下面幾個問題
1相關的頭文件和函數
1> 頭文件
利用頭文件,我們可以查看到runtime中的各個方法!
2> 相關應用
NSCoding(歸檔和解檔, 利用runtime遍歷模型對象的所有屬性)
字典 –> 模型 (利用runtime遍歷模型對象的所有屬性, 根據屬性名從字典中取出對應的值, 設置到模型的屬性上)
KVO(利用runtime動態產生一個類)
用於封裝框架(想怎麼改就怎麼改)
這就是我們runtime機制的只要運用方向
3> 相關函數
objc_msgSend : 給對象發送消息
class_copyMethodList : 遍歷某個類所有的方法
class_copyIvarList : 遍歷某個類所有的成員變量
class_…..
這是我們學習runtime必須知道的函數!
4.必備常識
1> Ivar : 成員變量
2> Method : 成員方法
從上面例子中我們看到我們定義的成員變量,如果要是動態創建方法,可以使用Method,
也許,看到這裏,你是否對runtime有了更深入的瞭解呢?在這裏,希望我們大家相互交流!有什麼錯誤之處,還請指正