2012-06-29 65 views
2

从 “objc.h”:在Cocoa中,Class类是如何定义的?

typedef struct objc_class *Class; 

但在 “runtime.h”:

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 

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

到底是什么Class

+0

'typedef'表明它是一个指向'struct objc_class'的指针,不是? – dasblinkenlight

+0

@dasblinkenlight他可能对'Class'成为'struct objc_class'成员感到困惑。 – trojanfoe

+0

是的,我很困惑 - 请你能向我解释它到底是什么吗?因为我认为这是两个标题之间的循环引用。 –

回答

10
typedef struct objc_class *Class; 

^这是objc_class指针的前向声明。它给了它不错的友好名称Class

现在让我们来看看objc_class结构: (删除的Objective-C 2.0检查,以缩短它)

struct objc_class { 
    Class isa; 
}; 
//This is really saying 
struct objc_class { 
    struct objc_class *isa; 
}; 

所以现在我们有一个指向它自己的类型结构。但你为什么要问?

Inside the Objective-C Runtime, Part 2

的Class由类ISA(类级)包含在其objc_method_list的 类类的方法指向两者。了解?在运行时使用的术语是,尽管对象的isa指向其Class的 ,但Class的isa指向对象的“meta Class”。

那么元类'isa指针呢?那么,这指向层次结构的根 类(大多数情况下为NSObject)。 (在基金会 框架中NSObject的一个子类的每个元类“isa”为 NSObject的实例)。是的,顺便说一句,NSObject的元类'isa指向 到同一个结构 - 它是一个循环引用,所以没有类'isa是 曾经是NULL。


所以根据这样的描述,当你创建一个类从NSObject继承你有一个isa指向指向指向它的根类(NSObject)它的元类的类类型包含一个循环引用本身。这就解释了它之所以为requires two steps to determine if an object is an instance or a class

比方说,你创建了以下类:

@interface MyClass : NSObject 
@end 
@implementation MyClass 
@end 


如果能够*遍历isa指针,你会得到如下:
* 你不能因为isa受到保护。请参阅下面的Cocoa with Love文章以创建您自己的实现。

Class c = myClassInstance->isa; //This would be the MyClass 
c = c->isa; //This would be MyClass' meta class 
c = c->isa; //This would be NSObjects meta class 
c = c->isa; //This going forward would still be the NSObjects meta class 
... 

一旦c == c->isa你会知道你是在根对象。请记住,Objective-C是C的一个超集,它本身并不具有面向对象的结构,如继承。这与其他实现细节(如构成完整类层次结构的超类的指针)一起允许Objective-C提供面向对象的功能。有关类和元类的更多信息请参见第可可后用爱:What is a meta-class in Objective-C?

+0

不错的答案,但一件小事...如果OP的代码是正确的,那么“移除Objective-C 2.0检查以缩短它”将移除* whole *定义 - 注意'struct'本身的最终'OBJC2_UNAVAILABLE'。 – CRD

+1

是的,它的确如此,你根本不应该使用'objc_class'结构。每个类都有一个'isa'作为它的第一个成员仍然是强制性的,所以我只是为示例添加了一个简短版本的结构。其余细节都是在'OBJC2'中定义的。 – Joe

+0

好的答案!非常感谢。 –

0

大约圆形参考:

如果如以下ISA定义不是一个指针,那么这成为一个循环引用。

struct objc_class { 
    struct objc_class isa; 
}; 

因为编译器无法计算objc_class的大小。

但是,在以下情况下(真正的定义),

struct objc_class { 
    struct objc_class *isa; 
}; 

ISA只是一个指针,所以没有这个问题。

相关问题