[英]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指針訪問超類? 但究竟是怎么回事? 這個怎么運作? 有人能解釋一下嗎?
剛檢查了源文件
Class class_getSuperclass(Class cls)
{
return _class_getSuperclass(cls);
}
#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
的指針
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.