在Cocoa中,如何定义Class类型?

时间:2012-06-29 16:15:07

标签: objective-c macos cocoa

来自“objc.h”:

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

2 个答案:

答案 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(Class'Class)指向的类包含   objc_method_list中的类'类方法。了解?该   运行时中使用的术语是指一个对象是一个点   对于它的类,一个类的isa指向对象的“元类”。

     

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


因此,根据该描述,当您创建一个继承自NSObject的类时,您有一个isa指向其类类型,该类类型指向其指向其根类的元类({{1其中包含对自身的循环引用。这解释了为什么requires two steps to determine if an object is an instance or a class

假设您创建了以下类:

NSObject


如果你能够*遍历isa指针,你会得到以下结果:
* 您不能,因为@interface MyClass : NSObject @end @implementation MyClass @end 受到保护。请参阅下面的Cocoa with Love帖子,以创建自己的实现。

isa

一旦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 ... ,您就会知道自己是根对象。请记住,Objective-C是C的正确超集,它本身不具有面向对象的构造,例如继承。这与其他实现细节(例如指向构成完整类层次结构的超类的指针)一起允许Objective-C提供面向对象的特性。有关类和元类的更多信息,请参阅Cocoa with Love上的帖子:What is a meta-class in Objective-C?

答案 1 :(得分:0)

关于循环引用:

如果isa被定义为不是指针如下,那么它将成为循环引用。

struct objc_class {
    struct objc_class isa;
}; 

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

但是,在以下情况(实际定义)中,

struct objc_class {
    struct objc_class *isa;
}; 

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