OC 中的 category

2018-09-17  本文已影响8人  LeeDev

在谈category的时候,就需要对比的看下扩展。

扩展:编译的时候决定,一般来说 是声明 私有的属性和变量
类别:主要是 在运行时决定 。同时 可以添加类/实例方法协议属性

struct category_t {
    const char *name;
    classref_t cls;
    struct method_list_t *instanceMethods;
    struct method_list_t *classMethods;
    struct protocol_list_t *protocols;
    struct property_list_t *instanceProperties;
    // Fields below this point are not always present on disk.
    struct property_list_t *_classProperties;

    method_list_t *methodsForMeta(bool isMeta) {
        if (isMeta) return classMethods;
        else return instanceMethods;
    }

    property_list_t *propertiesForMeta(bool isMeta, struct header_info *hi);
};

查看代码:
objc-runtime-new.mm 中找到入口 函数 Class realizeClass(Class cls), 在最后有个 methodizeClass(cls) 就是加入类别的方法.内部有

    // Install methods and properties that the class implements itself.
    method_list_t *list = ro->baseMethods();
    if (list) {
        prepareMethodLists(cls, &list, 1, YES, isBundleClass(cls));
        rw->methods.attachLists(&list, 1);
    }

然后我们 查看 methods.attachLists 方法
void attachLists(List* const * addedLists, uint32_t addedCount) {
        if (addedCount == 0) return;

        if (hasArray()) {
            //
            // many lists -> many lists
            uint32_t oldCount = array()->count;
            uint32_t newCount = oldCount + addedCount;
            //1.重新分配,相当于 用空间换时间
            setArray((array_t *)realloc(array(), array_t::byteSize(newCount)));
            array()->count = newCount;
            //内存移动 memmove(void *__dst, const void *__src, size_t __len)
            //2.【OldList1,OldList2,OldList3】 往后移动 addedCount 位置
            // array()->lists + 1 : 是相当于 偏移 sizeOf(array()->lists[0])的位置
            memmove(array()->lists + addedCount, array()->lists, 
                    oldCount * sizeof(array()->lists[0]));
            //memcpy(void *__dst, const void *__src, size_t __n)
            //3.相当于 把 新的数组【CateList1,CateList2】放入到 array()->lists 的起始位置
            memcpy(array()->lists, addedLists, 
                   addedCount * sizeof(array()->lists[0]));
        }
。。。。
}
上一篇下一篇

猜你喜欢

热点阅读