2

「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ですか?

4

2 に答える 2

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;
};

これで、独自のタイプを指す構造体ができました。しかし、なぜあなたは尋ねますか?

Objective-Cランタイムの内部からの抜粋、パート2

クラス'isa(クラス'クラス)が指すクラスには、そのobjc_method_listにクラス'クラスメソッドが含まれています。わかった?ランタイムで使用される用語は、オブジェクトのisaがそのクラスを指しているのに対し、クラスのisaはオブジェクトの「メタクラス」を指しているということです。

では、メタクラスのisaポインタはどうでしょうか?これは、階層のルートクラス(ほとんどの場合NSObject)を指します。(Foundationフレームワークでは、NSObjectのサブクラスの各メタクラスはNSObjectの「isa」インスタンスです。)そして、はい、NSObjectのメタクラス'isaは同じ構造体を指します。これは循環参照であるため、Class'isaはありません。 NULLです。


したがって、その説明によれば、継承するクラスを作成すると、NSObjectそれ自体への循環参照を含むisaルートクラス()を指すメタクラスを指すクラスタイプを指すがあります。これは、オブジェクトがインスタンスであるかクラスであるかを判断するために2つのステップが必要なNSObject理由を説明しています。

次のクラスを作成するとします。

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


isaポインタをトラバースできた場合*、次のようになります。
*は保護されているため、できません。isa独自の実装を作成するには、以下のCocoawithLoveの投稿を参照してください。

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がオブジェクト指向機能を提供できるようにします。クラスとメタクラスの詳細については、Cocoa with Loveの投稿を参照してください:Objective-Cのメタクラスとは何ですか?

于 2012-06-29T19:39:58.927 に答える
0

循環参照について:

isaが次のようにポインタではなく定義されている場合、それは循環参照になります。

struct objc_class {
    struct objc_class isa;
}; 

コンパイラがobjc_classのサイズを計算できなかったためです。

しかし、次の場合(実際の定義)、

struct objc_class {
    struct objc_class *isa;
}; 

isaは単なるポインタなので、問題はありません。

于 2013-05-18T03:59:47.850 に答える