runtime理解

runtime是一套可以進行一些非常底層的用OC無法實現的操作的純C語言的API。

點擊進入官方文檔

Objective-C類由一個指向objc_class結構體的指針來表示

//An opaque type that represents an Objective-C class.
typedef struct objc_class *Class;

objc/runtime.h中objc_class結構體的定義如下:

struct objc_class {
    Class isa  OBJC_ISA_AVAILABILITY;

#if !__OBJC2__
    Class super_class                       OBJC2_UNAVAILABLE;
    const char *name                        OBJC2_UNAVAILABLE;//類名
    long version                            OBJC2_UNAVAILABLE;
    long info                               OBJC2_UNAVAILABLE;
    long instance_size                      OBJC2_UNAVAILABLE;
    struct objc_ivar_list *ivars            OBJC2_UNAVAILABLE;//該類的成員變量列表
    struct objc_method_list **methodLists   OBJC2_UNAVAILABLE;
    struct objc_cache *cache                OBJC2_UNAVAILABLE;//緩存最近使用的方法
    struct objc_protocol_list *protocols    OBJC2_UNAVAILABLE;
#endif

} OBJC2_UNAVAILABLE;

一個類的實例由結構體objc_object來表示

//Represents an instance of a class.
struct objc_object {
    Class isa  OBJC_ISA_AVAILABILITY;
};

//A pointer to an instance of a class.
typedef struct objc_object *id;

當我們向一個Objective-C對象發送消息時,運行時庫會根據實例對象的isa指針找到這個實例對象所屬的類。Runtime庫會在類或其父類的方法列表中查詢並執行與消息對應的selector指向的方法。

元類(MetaClass)是一個類對象的類

(所有的類自身也是一個對象,我們可以向這個對象發送消息—調用類方法。)

meta-class也是一個類,也可以向它發送一個消息。Objective-C的設計者讓所有的meta-class的isa指向基類的meta-class,以此作爲它們的所屬類。即,任何NSObject繼承體系下的meta-class都使用NSObject的meta-class作爲自己的所屬類,而基類的meta-class的isa指針是指向它自己。這樣就形成了一個完美的閉環。

UIView *testView = [[UIView alloc] init];

NSLog(@"%p", self);
NSLog(@"%s", class_getName([testView class] ));
NSLog(@"class is %s, superclass is %s", class_getName([self class]),
      class_getName([self superclass]));

Class currentClass = [self class];
for (int i = 0; i < 3; i++) {
    NSLog(@"Following the isa pointer %d times gives %p", i, currentClass);
    currentClass = objc_getClass((__bridge void *)currentClass);
}

控制檯輸出:

0x7fa410c1f990
UIView
class is ViewController, superclass is UIViewController
Following the isa pointer 0 times gives 0x101c4e6c0
Following the isa pointer 1 times gives 0x0
Following the isa pointer 2 times gives 0x0

runtime對類和對象的操作

runtime提供了大量的函數來操作類與對象。類的操作方法大部分是以class_爲前綴的,而對象的操作方法大部分是以objc_或object_爲前綴。

對類操作

runtime提供的操作類的方法主要是針對結構體objc_class中的各個字段的。

//Returns the name of a class.
const char * class_getName(Class cls);
//Returns the superclass of a class.
Class class_getSuperclass(Class cls);
//Sets the superclass of a given class, return the old superclass for cls.
Class class_setSuperclass(Class cls, Class newSuper);
//Returns a Boolean value that indicates whether a class object is a metaclass.
BOOL class_isMetaClass(Class cls);
//Returns the size of instances of a class.
size_t class_getInstanceSize(Class cls);
//Returns the Ivar for a specified instance variable of a given class.
Ivar class_getInstanceVariable(Class cls, const char* name);
//Returns the Ivar for a specified class variable of a given class.
Ivar class_getClassVariable(Class cls, const char* name);
//Returns a description of the Ivar layout for a given class.
const char *class_getIvarLayout(Class cls);
...
發佈了29 篇原創文章 · 獲贊 6 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章