在Cocoa中,Class类型是如何定义的? [英] In Cocoa, how is the Class type defined?
问题描述
从objc.h:
typedef struct objc_class *
但在runtime.h中:
struct objc_class {
Class isa;
#if!__ OBJC2__
类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;
/ *使用`Class`而不是`struct objc_class *`* /
typedef struct objc_class * Class;
^这是 objc_class
指针。
现在让我们来看一下 objc_class
struct:
(删除Objective-C 2.0检查以缩短它)
struct objc_class {
Class isa;
};
//这真的说
struct objc_class {
struct objc_class * isa;
};
现在我们有一个struct指向它自己的类型。但你为什么要问?
指向的类'isa(类的类)包含
类的类方法在其objc_method_list。了解?运行时使用的
术语是,当对象的isa将
指向其类时,类的isa指向对象的meta Class。
那么元类的isa指针呢?好了,指向层次结构的根
类(在大多数情况下为NSObject)。 (在基金会
框架中每个元类的NSObject的子类的isa实例
NSObject。)和是的,顺便说一下,NSObject的元类'isa指向
struct - 它是一个循环引用,所以没有类'isa是
有NULL。
$ b b
因此,根据该描述,当你创建一个继承自 NSObject
的类时,你有一个 isa
它的类类型指向它的元类,它指向它的根类( NSObject
),它包含对自身的循环引用。这解释了为什么需要两个步骤来确定对象是否为实例或类。
假设你创建了以下类:
@interface MyClass:NSObject
@end
@implementation MyClass
@end
如果你能够遍历isa指针,你会得到以下结果:
* isa
受保护。请参阅下面的Cocoa with Love帖子来创建自己的实现。
类c = myClassInstance-& //这将是MyClass
c = c-> isa; //这将是MyClass的元类
c = c-> isa; //这将是NSObjects元类
c = c-> isa; //这将继续是NSObjects元类
...
code> c == c-> isa ,你会知道你是根对象。记住,Objective-C是C的一个适当的超集,它本身不具有面向对象的结构,如继承。这与其他实现细节(例如构成完整类层次结构的超类的指针)允许Objective-C提供面向对象的特征。有关类和元类的更多信息,请参阅Cocoa with Love的帖子: Objective-C中的元类是什么?
From "objc.h":
typedef struct objc_class *Class;
but in "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 *` */
What exactly is Class
?
typedef struct objc_class *Class;
^ That is a forward declaration for an objc_class
pointer. It gives it the nice friendly name Class
.
Now lets take a look at the objc_class
struct:
(Removing Objective-C 2.0 checks to shorten it up)
struct objc_class {
Class isa;
};
//This is really saying
struct objc_class {
struct objc_class *isa;
};
So now we have a struct that points to its own type. But why you ask?
Taken from Inside the Objective-C Runtime, Part 2
The Class pointed to by the Class' isa (the Class' Class) contains the Class' class methods in its objc_method_list. Got that? The terminology used in the runtime is that while an object's isa points to its Class, a Class's isa points to the object's "meta Class".
So what about a meta Class' isa pointer? Well, that points to the root class of the hierarchy (NSObject in most cases). (In the Foundation framework each meta class of a subclass of NSObject "isa" instance of NSObject.) And yes, by the way, NSObject's meta Class' isa points back to the same struct -- it's a circular reference so no Class' isa is ever NULL.
So according to that description when you create a class inheriting from NSObject
you have an isa
that points to its class type which points to its meta class which points to its root class (NSObject
) which contains a circular reference to itself. This explains the reason why it requires two steps to determine if an object is an instance or a class.
Lets say you create the following class:
@interface MyClass : NSObject
@end
@implementation MyClass
@end
If you were able* to traverse the isa pointer you would get the following:
*You can not since the isa
is protected. See Cocoa with Love post below for creating your own implementation.
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
...
Once c == c->isa
you will know you are at the root object. Remember that Objective-C is a proper superset of C, which does not natively have object-oriented constructs such as inheritance. This along with other implementation details, such as pointers to super classes which make up the full class hierarchy, allows Objective-C to provide object-oriented features. For more information on classes and meta-classes see the post on Cocoa with Love: What is a meta-class in Objective-C?
这篇关于在Cocoa中,Class类型是如何定义的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!