runtime-objc 類結構

運行時特性
Objectiv-C = C + Preprocessor(預處理器) + runtime
編譯器Clang把OC代碼編譯成C++代碼
運行時系統(tǒng)Runtime,執(zhí)行編譯后的代碼

核心功能
c結構體->封裝 -> OC類
執(zhí)行OC方法 ->消息機制 ->執(zhí)行C函數(shù)
編譯OC文件
clang -rewrite-objc Person.m
runtime 源碼
apple source:
https://opensource.apple.com/source/bojc4/
強制轉換(
((void()(id,SEL,int))(void)objc_mesgSend)
//通過這個設置可以進行objc_mesgSend直接調(diào)用 不用轉換
Build Settings -> Enable Strict Checking of objc_msgSend Calls -> NO

類的結構

 struct objc_class {
    Class _Nonnull isa  OBJC_ISA_AVAILABILITY; //類中isa

#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 methodList    OBJC2_UNAVAILABLE; //方法
    struct objc_cache * _Nonnull cache                       OBJC2_UNAVAILABLE; //方法
    struct objc_protocol_list * _Nullable protocols          OBJC2_UNAVAILABLE; //協(xié)議列表
#endif

} OBJC2_UNAVAILABLE;
/* Use `Class` instead of `struct objc_class *` */

類中的rw

struct class_rw_ext_t {
    const class_ro_t *ro;
    method_array_t methods; //方法列表
    property_array_t properties; //屬性類別
    protocol_array_t protocols; //協(xié)議列表
    char *demangledName;
    uint32_t version;
};

類中的ro

struct class_ro_t {
    uint32_t flags;
    uint32_t instanceStart;
    uint32_t instanceSize;
#ifdef __LP64__
    uint32_t reserved;
#endif

    const uint8_t * ivarLayout;
    
    const char * name;
    method_list_t * baseMethodList;
    protocol_list_t * baseProtocols;
    const ivar_list_t * ivars;

    const uint8_t * weakIvarLayout;
    property_list_t *baseProperties;

方法結構體

struct method_t {
    SEL name; //方法名
    const char *types;//方法類型
    MethodListIMP imp;//方法地址

    struct SortBySELAddress :
        public std::binary_function<const method_t&,
                                    const method_t&, bool>
    {
        bool operator() (const method_t& lhs,
                         const method_t& rhs)
        { return lhs.name < rhs.name; }
    };
};

協(xié)議列表

struct protocol_list_t {
    // count is pointer-sized by accident.
    uintptr_t count;
    protocol_ref_t list[0]; // variable-size

    size_t byteSize() const {
        return sizeof(*this) + count*sizeof(list[0]);
    }

};
struct protocol_t : objc_object {
    const char *mangledName; //協(xié)議名
    struct protocol_list_t *protocols; //協(xié)議列表
    method_list_t *instanceMethods;//實例方法
    method_list_t *classMethods; //類方法
    method_list_t *optionalInstanceMethods;//可選實例方法
    method_list_t *optionalClassMethods;//可選類方法
    property_list_t *instanceProperties;//實例屬性
    uint32_t size;   // sizeof(protocol_t)
    uint32_t flags;
    // Fields below this point are not always present on disk.
    const char **_extendedMethodTypes;
    const char *_demangledName;
    property_list_t *_classProperties;

    const char *demangledName();

    const char *nameForLogging() {
        return demangledName();
    }
}

屬性列表

class property_array_t : 
    public list_array_tt<property_t, property_list_t> 
{
    typedef list_array_tt<property_t, property_list_t> Super;

 public:
    property_array_t() : Super() { }
    property_array_t(property_list_t *l) : Super(l) { }

    property_array_t duplicate() {
        return Super::duplicate<property_array_t>();
    }
};

struct property_t {
    const char *name; //屬性名
    const char *attributes;//屬性內(nèi)容:strong weak 編碼等
};

類的結構

image

驗證上面這個經(jīng)典的類的結構模型
//創(chuàng)建一個person類并在方法中做出下列打印

    NSLog(@"Person 實例對象的地址:%@",self);//實例對象
    Class myclass = objc_getClass("CFPerson");//類對象
    NSLog(@"Person 的類地址:%p",myclass);
    Class metaClass = objc_getMetaClass("CFPerson");//元類對象的地址
    NSLog(@"Person 的元類地址:%p",metaClass);
    Class superClass = class_getSuperclass(myclass);//父類對象
    NSLog(@"Person 父類的地址:%@:%p",superClass,superClass);
    NSObject *obj = [NSObject new];//NSObject 實例對象
    NSLog(@"NSObject實例對象地址:%p",obj);
    Class objClass = objc_getClass("NSObject"); //類對象
    NSLog(@"NSObject 的類地址:%p",objClass);
    Class objMetaClass = objc_getMetaClass("NSObject");
    NSLog(@"NSObject 的元類地址:%p",objMetaClass); //元類對象的地址
    //父類對象
    Class objSuperClass = class_getSuperclass(objClass);
    NSLog(@"NSObject 父類的地址:%@:%p",objSuperClass,objSuperClass);
    //元類對象的父類的地址 應該是NSObject 的地址
    Class objMetaSuperClass = class_getSuperclass(objMetaClass);
    NSLog(@"objMetaSuperClass 的元類地址:%p",objMetaSuperClass);
    NSLog(@"---------");
    NSLog(@"@Person實例的isa:%p",object_getClass(self));
    NSLog(@"Person類的isa:%p",object_getClass(myclass));
    NSLog(@"Person元類的isa:%p",object_getClass(metaClass));
    
    NSLog(@"@NSObject實例的isa:%p",object_getClass(obj));
    NSLog(@"NSObject類的isa:%p",object_getClass(objClass));
    NSLog(@"NSObject元類的isa:%p",object_getClass(objMetaClass));

看先打印結果:

Person 實例對象的地址:<CFPerson: 0x1032948d0>
Person 的類地址:0x100008138
Person 的元類地址:0x100008110
Person 父類的地址:NSObject:0x7fff993fb118
NSObject實例對象地址:0x100410520
NSObject 的類地址:0x7fff993fb118
NSObject 的元類地址:0x7fff993fb0f0
NSObject 父類的地址:(null):0x0
objMetaSuperClass 的元類地址:0x7fff993fb118
 ---------
Person實例的isa:0x100008138
Person類的isa:0x100008110
Person元類的isa:0x7fff993fb0f0
NSObject實例的isa:0x7fff993fb118
NSObject類的isa:0x7fff993fb0f0
NSObject元類的isa:0x7fff993fb0f0

開始分析:
Person 的父類是NSObject ,因為Person繼承自NSObject,

Person 父類的地址:NSObject:0x7fff993fb118 和
NSObject 的類地址:0x7fff993fb118 地址是一樣的
NSObject 父類的地址:(null):0x0 NSObject 父類是nil
Person的isa指向其元類 其元類的isa 指向NSObject的元類
NSObject的元類的isa 指向的是自己

WeChate55585c6ef593efe89bb041b256a26ed.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容