根据传入的class的name获取对应的Class结构,主要使用了look_up_class方法,它从一个hash结构中根据名字获取对应的Class结构,如果没有找到则返回NULL。
使用的主要方法有: look_up_class, NXHashGet
只需要关注objc_getclass, look_up_class, NSHashGet三个方法即可。
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; }
将用户创建的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类和对象之一中是使用的old_class的结构,因此这里就采用old_class结构进行讲解了。新的和老的结构变化很大,主要的区别是class_t采用C++的一些方法,已经不是单纯的结构体,而是一个类;old_class还是一个纯粹的C结构体。
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++的函数,是纯粹的类。
/*********************************************************************** * 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); }
这里面的class的get和add主要就是一个hash的插入和获取,因此我就着重翻了一下hash结构的代码,内容还不少,不过由于大学的时候学过hash,就在这里抛砖引玉一下,希望大家给出更多的分析代码。具体内容且听下回分解hash。
原文:http://blog.csdn.net/lpstudy/article/details/22087099