IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> iOS 分类Category -> 正文阅读

[移动开发]iOS 分类Category

1.Category定义

Category的主要作用是为已经存在的类添加方法。
Objective-C 中的 Category 就是对装饰模式的一种具体实现。它的主要作用是在不改变原有类的前提下,动态地给这个类添加一些方法。

2.使用场景

  • 可以按照功能分组,放到不同的分类里,使类结构更清晰
  • 降低耦合性,同一个类可以有多个开发人员进行开发
  • 模拟多继承
  • 声明私有方法
  • 分解体积庞大的类文件
  • 把静态库的私有方法公开
  • 模拟多继承(另外可以模拟多继承的还有protocol)

3.特点

  • 1.分类是用于给原有类添加方法的,因为分类的结构体指针中,没有属性列表,只有方法列表。原则上讲它只能添加方法, 不能添加属性(成员变量),实际上可以通过其它方式添加属性?;
  • 2.分类中的可以写@property, 但不会生成setter/getter方法, 也不会生成实现以及私有的成员变量,会编译通过,但是引用变量会报错;
  • 3.如果分类中有和原有类同名的方法, 会优先调用分类中的方法, 就是说会忽略原有类的方法,同名方法调用的优先级为?分类 > 本类 > 父类
  • 4.如果多个分类中都有和原有类中同名的方法, 那么调用该方法的时候执行谁由编译器决定;编译器会执行最后一个参与编译的分类中的方法。
  • 5.运行时决议
  • 6.同名分类方法生效取决于编译顺序
  • 7.名字相同的分类会引起编译报错
  • 8.运行时决议

4.原理

一个类的类对象只有一个,存储着实例方法,元类对象也只有一个,存储着类方法
实例方法的调用轨迹是实例对象通过isa指针找到类对象,在类对象的方法列表中查找该方法,如果找不到,就通过superclass指针继续向上查找
类方法的调用轨迹是类对象通过isa指针找到元类对象,在元类对象的方法列表中查找该方法,如果找不到,就通过superclass指针继续向上查找

(1)分类的实例方法是被加载到类对象中,分类的类方法也是被加载到元类对象中

(2)编译时,分类是被编译成_category_t结构体,_category_t结构体存储着分类的实例方法列表、类方法列表、协议、属性。
分类实例方法、类方法不是在编译时,加载到类对象、元类对象中

在.cpp文件中可以导出这个结论

static struct _category_t _OBJC_$_CATEGORY_Person_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = 
{
    "Person",
    0, // &OBJC_CLASS_$_Person,
    (const struct _method_list_t *)&_OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_Test,
    (const struct _method_list_t *)&_OBJC_$_CATEGORY_CLASS_METHODS_Person_$_Test,
    0,
    0,
};

static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)
    unsigned int method_count;
    struct _objc_method method_list[1];
} _OBJC_$_CATEGORY_INSTANCE_METHODS_Person_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    1,
    {{(struct objc_selector *)"run", "v16@0:8", (void *)_I_Person_Test_run}}
};

static struct /*_method_list_t*/ {
    unsigned int entsize;  // sizeof(struct _objc_method)
    unsigned int method_count;
    struct _objc_method method_list[1];
} _OBJC_$_CATEGORY_CLASS_METHODS_Person_$_Test __attribute__ ((used, section ("__DATA,__objc_const"))) = {
    sizeof(_objc_method),
    1,
    {{(struct objc_selector *)"test", "v16@0:8", (void *)_C_Person_Test_test}}
};

struct _category_t {
    const char *name;
    struct _class_t *cls;
    const struct _method_list_t *instance_methods;
    const struct _method_list_t *class_methods;
    const struct _protocol_list_t *protocols;
    const struct _prop_list_t *properties;
};

(3)分类的数据是通过runtime动态加载到类信息中(类对象、元类对象中)

Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-01-08 14:08:36  更:2022-01-08 14:10:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:50:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码