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を聞いてください.