runtime 理解筆記

runtime 簡稱運行時,是系統運行的一種機制,在oc中經過c語言編寫一個運行系統庫。考進行一些很是底層的操做(oc沒法完成的)。函數

一、利用runtime,在程序運行過程當中,動態建立一個類(好比KVO)。spa

二、利用runtime, 在程序運行過程當中,動態的修改一個類的屬性\方法,添加屬性\方法。指針

三、遍歷一個類的全部成員變量。(字典轉模型)code

四、對象

 

對runtime要深刻理解,首先須要理解 isa,  objc_object, objc_classblog

在 Objective-C 中,類、對象和方法都是一個 C 的結構體,從 objc/objc.h(對象,objc_objectid)以及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)

元類(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
相關文章
相關標籤/搜索