簡體   English   中英

了解Objective-C運行時

[英]Understanding Objective-C runtime

這是Objective-C runtime programming guide的摘錄:

創建新對象時,將分配其內存,並初始化其實例變量。 對象變量中的第一個是指向其類結構的指針。 這個名為isa的指針使對象可以訪問它的類,並通過該類訪問它繼承的所有類。

isa在NSObject聲明如下:

Class   isa;

反過來, Class只不過是指向struct的指針

typedef struct objc_class *Class;

現在讓我們來看看這個結構:

struct objc_class {
Class isa;

#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

}

我們可以看到,在最新版本的Objective-C中,指向超類的指針(以及結構的所有其余成員除了另一個成員之外)都不可用。

所以我的問題是如果super_class指針不可用,對象如何才能訪問其超類? 是否可以通過另一個isa指針訪問超類? 但究竟是怎么回事? 這個怎么運作? 有人能解釋一下嗎?

剛檢查了源文件

objc-class.m

Class class_getSuperclass(Class cls)
{
    return _class_getSuperclass(cls);
}

runtime-new.mm

#define newcls(cls) ((class_t *)cls)

Class 
_class_getSuperclass(Class cls)
{
    return (Class)getSuperclass(newcls(cls));
}

static class_t *
getSuperclass(class_t *cls)
{
    if (!cls) return NULL;
    return cls->superclass;
}

所以Class實際上是指向class_t的指針

objc-運行時new.h

typedef struct class_t {
    struct class_t *isa;
    struct class_t *superclass;
    Cache cache;
    IMP *vtable;
    uintptr_t data_NEVER_USE;  // class_rw_t * plus custom rr/alloc flags

    class_rw_t *data() const { 
        return (class_rw_t *)(data_NEVER_USE & ~(uintptr_t)3); 
    }
    void setData(class_rw_t *newData) {
        uintptr_t flags = (uintptr_t)data_NEVER_USE & (uintptr_t)3;
        data_NEVER_USE = (uintptr_t)newData | flags;
    }

    bool hasCustomRR() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        return data_NEVER_USE & (uintptr_t)1;
#else
        return data()->flags & RW_HAS_CUSTOM_RR;
#endif
    }
    void setHasCustomRR(bool inherited = false);

    bool hasCustomAWZ() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        return data_NEVER_USE & (uintptr_t)2;
#else
        return data()->flags & RW_HAS_CUSTOM_AWZ;
#endif
    }
    void setHasCustomAWZ(bool inherited = false);

    bool isRootClass() const {
        return superclass == NULL;
    }
    bool isRootMetaclass() const {
        return isa == this;
    }
} class_t;

這是包含所有內容的結構

無論如何,這些都是內部實施細節,不應該依賴。 所以不要編寫依賴於這些的代碼,因為它們可能會在下次運行時更新時中斷

不要依賴類結構的任何內部。 - 你也不依賴其他好友實例變量! 你找房產

您可以安全地使用運行時在runtime.h

獲取超類egcall class_getSuperclass

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM