技術共有

Objective-C の isa は単純な構造ポインタではなくなりました

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Objective-C について学ぶ isa ポインタメモリ構造

Objective-C では、isa ポインタは、オブジェクトとクラスの間の重要な架け橋です。これは、ランタイム システムがオブジェクトの種類を識別するのに役立つだけでなく、メモリとパフォーマンスの最適化にも参加します。この記事では詳しく説明しますisa ポインターのメモリー構造 (初期および最新の実装における進化を含む)。

とは isa ポインタ?

すべての Objective-C オブジェクトには、 isa オブジェクトのクラスオブジェクトを指すポインター。クラスオブジェクト自体もオブジェクトであり、そのisa ポインタはメタクラス オブジェクトを指します。メタクラス オブジェクトにはクラス メソッドとそのメソッドが格納されます。isa ポインタは最終的にルート メタクラスを指します (通常はNSObject メタクラス)。

早い isa ポインタ構造体

初期の Objective-C 実装では、isa ポインタは単にクラス オブジェクトの構造を指します。初期の典型的な実装例を次に示します。

struct objc_object {
    Class isa; // 指向类对象的指针
};

typedef struct objc_class *Class; // Class 的本质是 objc_class 类型的结构体指针
struct objc_class {
    Class isa; // 指向元类对象的指针
    Class super_class; // 指向父类对象的指针
    // 其他类相关的元数据
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

この構造では次のようになります。

  • 物体 isa ポインタはクラスオブジェクトを指します。
  • オブジェのような isa ポインタはメタクラス オブジェクトを指します。
  • メタクラスオブジェクト isa ポインタはルート メタクラス オブジェクトを指します。

モダンな isa ポインタ構造体

64 ビット システムと最新の Objective-C ランタイムでは、isa ポインターは、より複雑な共用体として再設計されました (union isa_t )、これにはクラス オブジェクトへのポインターだけでなく、メモリの使用量とパフォーマンスを最適化するための他のフラグや情報も含まれています。以下はisa_t 構造の簡略化された例:

union isa_t {
    isa_t() { }
    isa_t(uintptr_t value) : bits(value) { }

    Class cls; // 指向类对象的指针
    uintptr_t bits; // 包含位域信息的位模式

    struct {
        uintptr_t nonpointer        : 1;  // 是否启用优化的 non-pointer isa
        uintptr_t has_assoc         : 1;  // 是否有关联对象
        uintptr_t has_cxx_dtor      : 1;  // 是否有 C++ 析构函数
        uintptr_t shiftcls          : 33; // 类指针(经过位移和压缩)
        uintptr_t magic             : 6;  // 调试用的魔数
        uintptr_t weakly_referenced : 1;  // 是否被弱引用
        uintptr_t deallocating      : 1;  // 是否正在释放
        uintptr_t has_sidetable_rc  : 1;  // 是否有辅助引用计数表
        uintptr_t extra_rc          : 19; // 额外的引用计数
    };
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

構造体フィールドの説明

  • 非ポインタ:指示する isa 非ポインター型であるかどうか (メモリーレイアウトの最適化、追加情報の保管)。
  • 関連がある: オブジェクトに関連付けられた参照があるかどうか (連想参照)。
  • cxx_dtor を持つ: オブジェクトに C++ デストラクターがあり、そのデストラクターを呼び出す必要があるかどうか。
  • シフト: オブジェクトのクラス情報を格納するクラス ポインター (移動および圧縮後)。
  • 魔法: デバッグと実行時検証に使用されるマジックナンバー。
  • 弱参照: オブジェクトが弱い参照によって指されているかどうか。
  • 割り当て解除: オブジェクトが解放されているかどうか。
  • サイドテーブルrc: オブジェクトの参照カウントが補助テーブル (Side Table) に格納されているかどうか。
  • 追加_rc: メモリ使用量を最適化するための追加の参照カウント。

参照カウントの保存と管理

初期の Objective-C 実装では、参照カウントは通常、オブジェクトの構造の一部としてオブジェクトに直接格納されていました。例えば:

struct objc_object {
    Class isa; // 指向类对象的指针
    uintptr_t retainCount; // 引用计数
};
  • 1
  • 2
  • 3
  • 4

最新の Objective-C ランタイムでは、参照カウントは次のように行われます。 isa 最適化されたポインタ構造とサイドテーブル補助データ構造が管理されます。

  • インライン参照カウント: 部分的な参照カウント情報が格納されます。 isa ポインタの最適化された構造では、例えばextra_rc 分野。
  • サイドテーブル: 参照カウントを超えた場合 isa ポインタが表現できる範囲を超えると、参照カウントはサイド テーブルと呼ばれる補助データ構造に格納されます。

モダンな isa ポインタの利点

  • メモリの最適化: より多くの情報 (参照カウント、フラグなど) を isa ポインタでは、他のメモリ領域へのアクセスが軽減され、パフォーマンスが向上します。
  • パフォーマンスの向上: 1 回のメモリ読み取りでより多くの情報を取得できるため、メモリ読み取り操作が削減されます。
  • より豊富なメタデータ: より多くの実行時情報を含めることができ、実行時の柔軟性と効率の向上に役立ちます。

使用例

開発者は多くの場合、直接対話することはありませんが、 isa ポインターは相互作用しますが、その構造を理解することは、デバッグとパフォーマンスの最適化に役立ちます。以下は、クラス情報にアクセスしてオブジェクトの型を表示する使用例です。

#import <Foundation/Foundation.h>
#import <objc/runtime.h>

@interface MyClass : NSObject
@end

@implementation MyClass
@end

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        MyClass *obj = [[MyClass alloc] init];
        Class cls = object_getClass(obj);
        NSLog(@"Class name: %s", class_getName(cls));
        
        // 访问 isa 指针信息(需要通过运行时函数)
        NSLog(@"isa pointer: %p", *(uintptr_t *)obj);
    }
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

要約する

isa ポインタは、クラス オブジェクトへの初期の単純なポインティングから最新の複雑なオブジェクトに至るまで、Objective-C ランタイムにおいて重要な役割を果たします。isa_t 構造は、メモリの使用量とパフォーマンスの最適化に役立ちます。理解するisa ポインタとメモリ構造の進化は、Objective-C の実行時のメカニズムをよりよく理解し、効率的なコードを書くのに役立ちます。

この記事が Objective-C についての理解を深めるのに役立つことを願っています。 isa ポインタのメモリ構造。ご質問やご提案がございましたら、ディスカッションのためにメッセージを残してください。