OC类和对象之三

OC类和对象之三

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三个方法即可。

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类和对象之一中是使用的old_class的结构,因此这里就采用old_class结构进行讲解了。新的和老的结构变化很大,主要的区别是class_t采用C++的一些方法,已经不是单纯的结构体,而是一个类;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主要就是一个hash的插入和获取,因此我就着重翻了一下hash结构的代码,内容还不少,不过由于大学的时候学过hash,就在这里抛砖引玉一下,希望大家给出更多的分析代码。具体内容且听下回分解hash。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值