在Cocoa中,Class类型是如何定义的? [英] In Cocoa, how is the Class type defined?

查看:117
本文介绍了在Cocoa中,Class类型是如何定义的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从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指向它自己的类型。但你为什么要问?



取自在Objective-C运行时,第2部分


指向的类'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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆