Objective-C objc_class紹介


Objective-C objc_class紹介
NSObject
Object-CではNSObjectがほとんどのクラスのルートクラスです.
@interface NSObject <NSObject> {
    Class isa  OBJC_ISA_AVAILABILITY;
}

クラスのisaプロパティがあります.
アップルはすでにObjC runtimeコードをオープンソースして、私達はダウンロードして、Classがいったい何なのかを見てみましょうhttp://opensource.apple.com/tarballs/objc4/objc4-493.9.tar.gz
objc_class
ファイルにClassの定義が表示されます
typedef struct objc_class *Class;
typedef struct objc_object {
    Class isa;
} *id;

Classはobjc_ですclass構造タイプのポインタ、idはobjc_object構造タイプのポインタ
objc_classの定義はで見つけた
struct objc_class {
    Class isa;
    Class super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct objc_ivar_list *ivars;
    struct objc_method_list **methodLists;
    struct objc_cache *cache;
    struct objc_protocol_list *protocols;

} OBJC2_UNAVAILABLE;

次に各属性の意味を見てみましょう
isa
Objective-C Classタイプのポインタです.インスタンスオブジェクトにはisaの属性があり、Classを指し、Classにもisaの属性があり、meteClassを指す.ここには、Objective-Cのクラス定義がオブジェクトである点がある.
super_class
クラスの親を指します.クラスが最上位レベルのルートクラス(NSObjectやNSProxyなど)である場合、super_classはNULLです.
彼らの関係は?http://www.sealiesoftware.com/blog/class%20diagram.pdf
Objective-C objc_class 介绍_第1张图片
name
まず次のコードを見てみましょう
id objc_getClass(const char *aClassName)
{
    if (!aClassName) return Nil;

    // NO unconnected, YES class handler
    return look_up_class(aClassName, NO, YES);
}

PRIVATE_EXTERN id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler)
{
    BOOL includeClassLoader = YES; // class loader cannot be skipped
    id result = nil;
    struct old_class query;

    query.name = aClassName;

 retry:

    if (!result  &&  class_hash) {
        // Check ordinary classes
        mutex_lock (&classLock);
        result = (id)NXHashGet(class_hash, &query);
        mutex_unlock (&classLock);
    }

    if (!result  &&  includeUnconnected  &&  unconnected_class_hash) {
        // Check not-yet-connected classes
        mutex_lock(&classLock);
        result = (id)NXHashGet(unconnected_class_hash, &query);
        mutex_unlock(&classLock);
    }

    if (!result  &&  includeClassLoader  &&  _objc_classLoader) {
        // Try class loader callback
        if ((*_objc_classLoader)(aClassName)) {
            // Re-try lookup without class loader
            includeClassLoader = NO;
            goto retry;
        }
    }

    if (!result  &&  includeClassHandler  &&  objc_classHandler) {
        // Try class handler callback
        if ((*objc_classHandler)(aClassName)) {
            // Re-try lookup without class handler or class loader
            includeClassLoader = NO;
            includeClassHandler = NO;
            goto retry;
        }
    }

    return result;
}

struct old_class {
    struct old_class *isa;
    struct old_class *super_class;
    const char *name;
    long version;
    long info;
    long instance_size;
    struct old_ivar_list *ivars;
    struct old_method_list **methodLists;
    Cache cache;
    struct old_protocol_list *protocols;
    // CLS_EXT only
    const uint8_t *ivar_layout;
    struct old_class_ext *ext;
};

objc_getClassは文字列からクラスを返し、look_up_class、まずold_を作成しますclassオブジェクト、nameはこの文字列に割り当てられ、見つかったらold_を返します.class.old_を見てclassの構造からnameという属性が格納されている値がクラスの名前であることがわかります(実はnameは名前ではありませんか)
version
クラスのバージョン情報、デフォルトは0
info
実行時に使用するビットID.
instance_size
クラスのインスタンス変数のサイズ
ivars
struct objc_ivar_list {
    int ivar_count;
    /* variable length structure */
    struct objc_ivar ivar_list[1];
}

メンバー変数の配列
methodLists
メソッド定義の配列
struct objc_method_list {
    struct objc_method_list *obsolete;
    int method_count;
    /* variable length structure */
    struct objc_method method_list[1];
}

objc_cache
最近使用した方法を指す.メソッド呼び出しの最適化に用いる.
struct objc_cache {
    unsigned int mask /* total = mask + 1 */;
    unsigned int occupied;
    Method buckets[1];
};

protocols
プロトコルの配列
struct objc_protocol_list {
    struct objc_protocol_list *next;
    long count;
    Protocol *list[1];
};