Category详解

 

1.概念:Category是Objective-C 2.0 之后添加的语言特性,它可以为已经存在的类添加方法

2.作用

2.1:可以减少单个文件的体积

2.2.可以把不同的功能组织到不同的 Category 中

2.3.可以按需加载

2.4.声明私有方法

2.5.把 framework 的私有方法公开

3.源码:源码链接:https://github.com/RetVal/objc-runtime

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);

};

4.Category和extension(扩展)的区别

4.1.extension:

类的一部分

编译时期决定

隐藏类的私有属性

对象的内存布局已确定

4.2.Category:

运行时期

不能添加变量

5.category从编译到运行时期的过程

5.1.编译时期:创建一个category,通过命令:clang -rewirte-objc category.m,可以看到它被加载到了__DATA数据段的__objc_catlist中

5.2.运行时期调用顺序:

5.2.1.dyld_start:dyld是苹果的动态加载器,用来加载动态库,其中包括libobjc(OC和runtime)

可以通过打符号断点看到

5.2.2._objc_init:入口函数,读取Mach-o文件对应的Segment section,并根据其中的数据代码信息,完成为OC的内存布局,以及初始化runtime相关的数据结构

5.2.3.map_images:dyld将image(Mach-o格式的二进制文件)加载进内存

5.2.4.load_images:dyld初始化image,load方法也在这个时候调用

5.2.5.umap_image:dyld将image移除内存

5.2.6.read_image:读取oc相关的section,通过读取seciton段来进行初始化

map_images_nolock函数中找到_read_images

5.2.7._getObjc2CategoryList:读取__objc_catlist

5.2.8.addUnattachedCategoryForClass:把分类加载到类当中

5.2.9.NXMapInsert:cats(Category)和cls(类)建立关联

5.2.10.remethodizeClass:对当前cls 的内存布局进行重新排列

5.2.11.attachCategories:把当前的cats附加到cls中

5.2.12.prepareMethodLists:准备当前类的方法列表

5.2.13.attachLists:通过memmove和memcpy,把分类的方法添加到原来的方法列表当中

6.总结:

6.1.通过5.2.7_getObjc2CategoryList读取__objc_catlist secition段记录中所有的category,存放到category_t 数组中

6.2.依次读取category_t数组

6.3.cat和cls进行映射

6.4.通过remethodizeClass修改method_list结构,这里涉及到memove和memcpy

7.动态添加属性

7.1.AssociationsManager中存放了一个map(AssociationsHashMap),map中的key是当前对象地址的按位取反,value是一个迭代器,也是一个map,迭代器map中的key是自定义的标识,value是ObjcAssociation(用户自定义的,用来存储当前的关联属性

 

7.2.关联对象的释放是在源对象被销毁时释放(dealloc),通过对象的指针来释放关联对象,具体调用的是_object_remove_assocations中的ReleaseValue

8.load方法:

8.1.一个类的load方法在所有的父类都调用完之后调用

8.2.category的调用load方法在类的调用load方法之后调用

8.3.category之间的调用顺序:通过dyld调整调用顺序和编译顺序有关

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AVAudioSession是iOS中用于管理应用程序的音频会话的类。它允许应用程序控制和配置音频功能,如音频输入、输出、音频路由、音频处理等。AVAudioSession的目的是提供一个统一的接口,以便应用程序可以与设备的音频系统进行交互,无论是播放音乐、录制语音还是进行VoIP通话。 AVAudioSession有几个重要的概念和属性: 1. Category(分类):用于描述应用程序对音频的使用情况,如播放音乐、录制音频、播放通话等。不同的分类具有不同的优先级和行为。应用程序可以根据需要选择适当的分类,并在需要时进行切换。 2. Mode(模式):用于描述音频会话的详细行为。不同的模式针对不同的应用场景进行了优化,如游戏、音乐播放、通话等。应用程序可以根据需要设置适当的模式。 3. Route(路由):描述音频信号的路径,如扬声器、听筒、耳机等。应用程序可以查询当前的音频路由,并根据需要进行调整。 4. Options(选项):用于配置音频会话的其他参数,如混音、静音、中断处理等。 AVAudioSession还提供了一些其他的功能和方法,如设置音频输入、输出的硬件设备、监测耳机插拔事件、处理音频会话的中断和恢复等。 总之,AVAudioSession是一个强大的音频管理类,允许应用程序轻松控制和配置音频功能,并为各种应用场景提供了灵活的接口。通过使用AVAudioSession,开发者可以实现各种复杂的音频操作,提供优质的音频体验给用户。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值