runtime 簡稱運行時,是系統運行的一種機制,在oc中經過c語言編寫一個運行系統庫。考進行一些很是底層的操做(oc沒法完成的)。函數
一、利用runtime,在程序運行過程當中,動態建立一個類(好比KVO)。spa
二、利用runtime, 在程序運行過程當中,動態的修改一個類的屬性\方法,添加屬性\方法。指針
三、遍歷一個類的全部成員變量。(字典轉模型)code
四、對象
對runtime要深刻理解,首先須要理解 isa, objc_object, objc_classblog
在 Objective-C 中,類、對象和方法都是一個 C 的結構體,從 objc/objc.h
(對象,objc_object
,id
)以及objc/runtime.h
(其它,類,方法,方法列表,變量列表,屬性列表等相關的)以及中,咱們能夠找到他們的定義。io
isa指針是和Class同類型的objc_class結構指針,類對象的指針指向其所屬的類,即元類。元類中存儲着類對象的類方法,當訪問某個類的類方法時會經過該isa指針從元類中尋找方法對應的函數指針。class
objc.h : objc_objectimport
/// Represents an instance of a class. struct objc_object { Class _Nonnull isa OBJC_ISA_AVAILABILITY; };
runtime.h : objc_class 變量
struct objc_class { Class _Nonnull isa OBJC_ISA_AVAILABILITY; #if !__OBJC2__ Class _Nullable super_class OBJC2_UNAVAILABLE; const char * _Nonnull name OBJC2_UNAVAILABLE; long version OBJC2_UNAVAILABLE; long info OBJC2_UNAVAILABLE; long instance_size OBJC2_UNAVAILABLE; struct objc_ivar_list * _Nullable ivars OBJC2_UNAVAILABLE; struct objc_method_list * _Nullable * _Nullable methodLists OBJC2_UNAVAILABLE; struct objc_cache * _Nonnull cache OBJC2_UNAVAILABLE; struct objc_protocol_list * _Nullable protocols OBJC2_UNAVAILABLE; #endif } OBJC2_UNAVAILABLE; /* Use `Class` instead of `struct objc_class *` */
說明:
一、對象是一個objc_object
的結構體,類是一個objc_class
的結構體.
二、對象的isa指向對象類自己,包含了當前對象指向的類的信息; 類的isa指向元類,包含了類對象指向的元類(meta-class)的信息。
三、NSObject
類中包含的是一個objc_class
結構體類型的isa
,指向該對象對應的類。
元類(Metaclass)就是類對象的類,每一個類都有本身的元類,也就是objc_class
結構體裏面isa
指針所指向的類. Objective-C的類方法是使用元類的根本緣由,由於其中存儲着對應的類對象調用的方法即類方法。
當向對象發消息,runtime會在這個對象所屬類方法列表中查找發送消息對應的方法,但當向類發送消息時,runtime就會在這個類的meta class方法列表裏查找。全部的meta class,包括Root class,Superclass,Subclass的isa都指向Root class的meta class,這樣可以造成一個閉環。
結構圖:
因此由上圖能夠看到,在給實例對象或類對象發送消息時,尋找方法列表的規則爲:
元類,就像以前的類同樣,它也是一個對象,也能夠調用它的方法。因此這就意味着它必須也有一個類。全部的元類都使用根元類做爲他們的類。好比全部NSObject的子類的元類都會以NSObject的元類做爲他們的類。
根據這個規則,全部的元類使用根元類做爲他們的類,根元類的元類則就是它本身。也就是說基類的元類的isa指針指向他本身。
技巧:
一、#import <objc/message.h> 包含了 #include <objc/objc.h>, #include <objc/runtime.h>
#ifndef _OBJC_MESSAGE_H #define _OBJC_MESSAGE_H #include <objc/objc.h> #include <objc/runtime.h> #ifndef OBJC_SUPER #define OBJC_SUPER