OCクラスとオブジェクトの3

5369 ワード

OCクラスとオブジェクトの3


1,objc_getClass


1.1、簡単に述べる


受信したclassのnameに基づいて対応するClass構造を取得し,主にlook_を用いた.up_classメソッドは、hash構造から名前に基づいて対応するClass構造を取得し、見つからない場合はNULLを返します.
使用する主な方法は、look_です.up_class, NXHashGet

1.2、ライブラリコード


objc_に注目するだけgetclass, look_up_class,NSHashGetの3つの方法でよい.
id objc_getClass(const char *aClassName)
{
    if (!aClassName) return Nil;
 
    // NO unconnected, YES class handler
    return look_up_class(aClassName,NO, YES);
}
// class. old_class Class 。
PRIVATE_EXTERN id look_up_class(const char *aClassName, BOOL includeUnconnected, BOOL includeClassHandler)
{
    id result = nil;
    struct old_class query;
    query.name = aClassName;
 
    if (!result &&  class_hash) {
        // Check ordinary classes
        mutex_lock (&classLock);
        // NXHashGet query
        result = (id)NXHashGet(class_hash,&query);
        mutex_unlock (&classLock);
    }
    return result;
}



2,objc_addClass


2.1、簡単に述べる


ユーザーが作成したclassをシステムのHash構造に追加し、追加したClass構造はobjc_を使用できます.getClassが入手できました.この方法は既に廃棄されているが,従来のClassへの加入の流れを記述しているので簡単に述べる.重要な方法はNXHashInsert,objc_ですaddRegisteredClassはGCゴミ回収のためのもので、しばらく考えなくてもいいです.
現在:
callingobjc_を使用できます.AllocateClassPairはClassを作成します.そしてclass_を通ってaddMethodand class_addIvar.このClassのプロパティを設定し、objc_を呼び出すregisterClassPairはClassをシステムに追加しますが、彼らが使用している構造体は新しいclassです.tの構造は、古いoldではありません.classの構造で、OCクラスとオブジェクトの1つで使用しているold_classの構造なので、ここではold_を採用します.class構造について説明しました.新しい構造と古い構造の変化が大きく、主な違いはclassです.tはC++のいくつかの方法を採用して、すでに単純な構造体ではありませんて、1つの類です;old_classは純粋なC構造体でもある.

2.2、新旧構造の説明

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;
    structold_protocol_list *protocols;
    // CLS_EXT only
    const uint8_t *ivar_layout;
    struct old_class_ext*ext;
};

クラスですが、純粋な構造体の説明です.
 
typedef struct class_t {
    struct class_t *isa;
    struct class_t *superclass;
    Cache cache;
    IMP *vtable;
    uintptr_tdata_NEVER_USE;  // class_rw_t * plus flags
 
    class_rw_t *data() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        return (class_rw_t*)(data_NEVER_USE & ~3UL);
#else
        return (class_rw_t *)data_NEVER_USE;
#endif
    }
    void setData(class_rw_t *newData) {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
        uintptr_tflags = (uintptr_t)data_NEVER_USE & 3UL;
       data_NEVER_USE = (uintptr_t)newData | flags;
#else
        data_NEVER_USE = (uintptr_t)newData;
#endif
    }
 
    bool hasCustomRR() const {
#if CLASS_FAST_FLAGS_VIA_RW_DATA
      return data_NEVER_USE& 1UL;
#else
        return (data()->flags & RW_HAS_CUSTOM_RR);
#endif
    }
    voidsetHasCustomRR();
    voidunsetHasCustomRR();
 
    boolhasIvarReleaser() const {
        return (data()->flags & RW_HAS_IVAR_RELEASER);
    }
    voidsetHasIvarReleaser();
 
    bool isRootClass() const {
        return superclass == NULL;
    }
    boolisRootMetaclass() const {
        return isa == this;
    }
} class_t;

C++の関数が多く、純粋なクラスです.

2.3、ライブラリコード

/***********************************************************************
 * objc_addClass.  Add the specified class to the table of knownclasses,
 * after doing a little verification and fixup.
 **********************************************************************/
void        objc_addClass           (Class cls_gen)
{
    struct old_class *cls =oldcls(cls_gen);
 
    OBJC_WARN_DEPRECATED;
 
    // Synchronize access to hash table
    mutex_lock (&classLock);
 
    // Make sure both the class and themetaclass have caches!
    // Clear all bits of the info fields exceptCLS_CLASS and CLS_META.
    // Normally these bits are already clearbut if someone tries to cons
    // up their own class on the fly they mightneed to be cleared.
    if (cls->cache == NULL) {
        cls->cache = (Cache)&_objc_empty_cache;
        cls->info = CLS_CLASS;
    }
 
    if (cls->isa->cache == NULL) {
        cls->isa->cache = (Cache)&_objc_empty_cache;
        cls->isa->info = CLS_META;
    }
 
    // methodLists should be:
    // 1. NULL (Tiger and later only)
    // 2. A -1 terminated method list array
    // In either case, CLS_NO_METHOD_ARRAYremains clear.
    // If the user manipulates the method listdirectly,
    // they must use the magic private format.
 
    //  , cls hash 
    (void) NXHashInsert (class_hash,cls);
    objc_addRegisteredClass((Class)cls);
 
    // Superclass is no longer a leaf for cacheflushing
    if (cls->super_class &&(cls->super_class->info & CLS_LEAF)) {
       _class_clearInfo((Class)cls->super_class, CLS_LEAF);
        _class_clearInfo((Class)cls->super_class->isa,CLS_LEAF);
    }
 
    // Desynchronize
    mutex_unlock (&classLock);
}

2.4,Hash


この中のclassのgetとaddは主に1つのhashの挿入と取得なので、私は重点的にhash構造のコードをひっくり返して、内容はまだ少なくありませんが、大学の时にhashを学んだことがあるので、ここでレンガを投げて玉を引いて、みんながもっと多くの分析コードを与えることを望んでいます.具体的な内容は、次回の分解hashを聞いてください.