移动开发—分类-Category

本文详细探讨了iOS开发中Category的功能,包括如何为类添加方法、属性,以及分类的加载顺序。重点解析了_category_t结构体,分析了_methodizeClass、attachCategories等关键方法在类加载过程中的作用,揭示了分类不会覆盖原有方法的原因。同时,文章还讨论了分类添加属性的问题,指出由于Category没有成员列表,因此不能直接添加属性,但可以通过关联对象实现为类动态添加属性的功能。
摘要由CSDN通过智能技术生成

分类-Category

分类的功能
在OC中,我们可以使用分类为类添加方法,属性.也可以覆盖类原有的方法,自己添加新的实现.(说是覆盖,其实不然.在稍后分类加载时间会解释原因)

分类的结构

const char *name;
    classref_t cls;
    WrappedPtr<method_list_t, PtrauthStrip> instanceMethods;
    WrappedPtr<method_list_t, PtrauthStrip> 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);

    protocol_list_t *protocolsForMeta(bool isMeta) {
        if (isMeta) return nullptr;
        else return protocols;
    }

从源码可以看出,分类是名为 category_t 的结构体类型数据.

category_t的成员
instanceMethods:实例方法
classMethods:类方法
protocols:协议
instanceProperties:实例属性
_classProperties:类属性
分类的加载顺序
分析iOS App启动时的一系列方法,可以看到分类的加载规则.下面是一系列经过的方法

_objc_init ==> map_images ==> map_images_nolock ==> _read_images ==> remethodizeClass ==> attachCategories

_

read_images
// Discover classes. Fix up unresolved future classes. Mark bundle classes.

    for (EACH_HEADER) {
        if (! mustReadClasses(hi)) {
            // Image is sufficiently optimized that we need not call readClass()
            continue;
        }

        bool headerIsBundle = hi->isBundle();
        bool headerIsPreoptimized = hi->isPreoptimized();

        classref_t *classlist = _getObjc2ClassList(hi, &count);
        for (i = 0; i < count; i++) {
            Class cls = (Class)classlist[i];
            Class newCls = readClass(cls, headerIsBundle, headerIsPreoptimized);

            if (newCls != cls  &&  newCls) {
                // Class was moved but not deleted. Currently this occurs 
                // only when the new class resolved a future class.
                // Non-lazily realize the class below.
                resolvedFutureClasses = (Class *)
                    realloc(resolvedFutureClasses, 
                            (resolvedFutureClassCount+1) * sizeof(Class));
                resolvedFutureClasses[resolvedFutureClassCount++] = newCls;
            }
        }
    }
 // Discover protocols. Fix up protocol refs.
    for (EACH_HEADER) {
        extern objc_class OBJC_CLASS_$_Protocol;
        Class cls = (Class)&OBJC_CLASS_$_Protocol;
        assert(cls);
        NXMapTable *protocol_map = protocols();
        bool isPreoptimized = hi->isPreoptimized();
        bool isBundle = hi->isBundle();

        protocol_t **protolist = _getObjc2ProtocolList(hi, &count);
        for (i = 0; i < count; i++) {
            readProtocol(protolist[i], cls, protocol_map, 
                         isPreoptimized, isBundle);
        }
    }
 // Discover categories.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值