当前位置: 首页 > news >正文

iOS Category

原理:

【iOS】——分类、扩展和关联对象_ios 为什么分类不能加成员变量-CSDN博客

面试题:

1.Category和Extension区别?

在 Objective-C 中,Category 和 Extension 是两种用于向现有类添加新功能的机制,但它们各有特点和用途。以下是 Category 和 Extension 的主要区别:

Objective-C Category(分类)
  1. 目的与用途

    • Category 主要用于向现有的类添加新的方法。
    • 它不能用于添加新的实例变量。
  2. 加载时机

    • Category 中的方法是在运行时动态添加到类的方法列表中。
    • 如果 Category 中的方法与原始类或其他 Category 中的方法同名,会产生覆盖效果,最后编译的 Category 会占据优先权。
  3. 可见性

    • Category 可以声明在任何地方,它允许在不修改原始类定义的情况下添加新方法。
    • Category 可以分布在不同的文件中,这有助于模块化和分散类的实现。
  4. 头文件

    • Category 需要单独的头文件(.h)和实现文件(.m)。
Objective-C Extension(类扩展)
  1. 目的与用途

    • Extension 通常用于为类声明私有属性、方法或添加新的实例变量(在类的实现文件中)。
    • Extension 是匿名的,通常在类的实现文件(.m 文件)中定义。
  2. 加载时机

    • Extension 中的方法和属性是在编译时合并到类的定义中的,和类本身的方法一样。
  3. 可见性

    • Extension 通常用于私有化目的,用于隐藏类的私有接口,不希望外部访问。
  4. 头文件

    • 由于它们通常用于私有化目的,Extension 一般不需要单独的头文件。
共同点
  • 两者都用于为现有的类添加新功能。
  • 两者都不能添加新的存储属性(实例变量),但 Extension 可以声明属性来添加对私有实例变量的访问,只要这些实例变量是在类的主实现块中声明的。
主要区别
  • 可见性和用途:Category 更适合公开地添加新方法,而 Extension 通常用于添加私有方法、属性和实例变量。
  • 加载时机:Category 的方法是在运行时添加的,而 Extension 的方法在编译时就已经被合并到类中。
  • 添加实例变量:Extension 可以在类的实现文件中声明新的实例变量,Category 则不能。

了解这些区别有助于在 Objective-C 开发中合理地使用 Category 和 Extension。在 Swift 中,由于不支持向现有类型添加存储属性,Category 和 Extension 的概念被统一为 Extensions,它们更加强大和灵活。

2.Category设计成不能添加属性,这样做有什么好处?

Objective-C 中 Category 的设计不允许直接添加实例变量或属性,主要是出于以下几个原因和考虑:

  1. 兼容性和安全性:Category 的主要用途是为现有的类添加新方法,而不是改变类的内部状态或结构。如果允许在 Category 中添加实例变量,那么在运行时对类的内存布局进行修改可能会引起严重的兼容性问题,尤其是对于已经在使用的类实例。不允许添加实例变量有助于保持类的内部结构稳定和安全。

  2. 简化运行时的实现:Objective-C 的运行时系统在加载类定义时会确定类的大小和布局。如果允许 Category 添加实例变量,运行时系统就需要处理类布局的动态变化,这将大大增加复杂性,并可能影响性能。不允许添加实例变量简化了运行时的实现。

  3. 分离责任:Category 主要用于为类扩展方法,而不是改变类的内部表示。如果需要添加属性和实例变量,应该使用类的子类或扩展(Extension)。扩展可以向类添加私有的属性和实例变量,但必须在类的主实现文件中定义。这种分离有助于代码的组织和维护。

  4. 避免冲突:如果 Category 能够添加实例变量,当多个 Category 尝试添加同名的实例变量时,冲突和不一致的情况将难以避免。这样的设计有助于减少因冲突导致的错误。

虽然 Category 不能直接添加实例变量,Objective-C 提供了关联对象(Associated Objects)机制,允许开发者在运行时关联额外的数据到对象实例上。通过关联对象,可以达到类似添加属性的效果,但这种方式并不修改原有类的内部结构,而是使用 Objective-C 运行时的特性来实现。这种方法提供了灵活性,同时保持了类定义的稳定和安全。

3.OC为什么不能添加属性,这样设计的好处是什么? 

Objective-C 中 Category 的设计不允许直接添加实例变量或属性,主要是出于以下几个原因和考虑:

  1. 兼容性和安全性:Category 的主要用途是为现有的类添加新方法,而不是改变类的内部状态或结构。如果允许在 Category 中添加实例变量,那么在运行时对类的内存布局进行修改可能会引起严重的兼容性问题,尤其是对于已经在使用的类实例。不允许添加实例变量有助于保持类的内部结构稳定和安全。

  2. 简化运行时的实现:Objective-C 的运行时系统在加载类定义时会确定类的大小和布局。如果允许 Category 添加实例变量,运行时系统就需要处理类布局的动态变化,这将大大增加复杂性,并可能影响性能。不允许添加实例变量简化了运行时的实现。

  3. 分离责任:Category 主要用于为类扩展方法,而不是改变类的内部表示。如果需要添加属性和实例变量,应该使用类的子类或扩展(Extension)。扩展可以向类添加私有的属性和实例变量,但必须在类的主实现文件中定义。这种分离有助于代码的组织和维护。

  4. 避免冲突:如果 Category 能够添加实例变量,当多个 Category 尝试添加同名的实例变量时,冲突和不一致的情况将难以避免。这样的设计有助于减少因冲突导致的错误。

虽然 Category 不能直接添加实例变量,Objective-C 提供了关联对象(Associated Objects)机制,允许开发者在运行时关联额外的数据到对象实例上。通过关联对象,可以达到类似添加属性的效果,但这种方式并不修改原有类的内部结构,而是使用 Objective-C 运行时的特性来实现。这种方法提供了灵活性,同时保持了类定义的稳定和安全。

4.Swift中有Category吗?

在 Swift 中,没有名为 “Category” 的概念,但有一个类似的功能被称为 “Extensions”。Swift 的 Extensions 与 Objective-C 中的 Categories 在某些方面类似,因为它们都允许开发者为现有类型添加新的功能,但是在 Swift 中 Extensions 功能更加强大和灵活。

Swift 的 Extensions 允许你为现有的类、结构体、枚举类型或者协议类型添加新的功能,这包括:

  • 添加新的计算实例属性和计算类型属性
  • 定义实例方法和类型方法
  • 提供新的初始化器
  • 定义下标
  • 定义和使用新的嵌套类型
  • 使现有类型遵循某个协议

与 Objective-C 的 Categories 不同,Swift 的 Extensions 可以添加计算属性,但是它们仍然不能添加存储属性。如果你需要存储额外的信息,你可以使用关联对象,或者考虑使用其他设计模式,例如组合或继承。

下面是一个 Swift Extension 的示例:

extension String {func reversedString() -> String {return String(self.reversed())}
}let example = "Hello, World!"
let reversed = example.reversedString() // 输出 "!dlroW ,olleH"

在这个例子中,我们为 String 类型添加了一个新的方法 reversedString,它会返回字符串的反向表示。这个方法可以被任何 String 实例调用,就像它是 String 类型原生支持的方法一样。

Swift 的 Extensions 是 Swift 语言强大的特性之一,它们极大地增强了代码的可扩展性和复用性,同时也保持了类型安全和清晰的代码结构。

5.OC extension和Swift extension有什么区别

Objective-C 的 Extensions 和 Swift 的 Extensions 都是对现有类扩展新功能的机制,但它们在概忈、功能和限制上有一些重要区别:

  1. 概念和用途

    • Objective-C Extensions 通常用于为类添加私有方法和属性。它们只能在类的实现文件中定义,通常用来隐藏不想公开的接口。
    • Swift Extensions 可以添加到类、结构体、枚举或协议等任何类型上,并且可以在任何地方定义。Swift 的扩展更加灵活,可以用来添加新方法、计算属性、嵌套类型、协议遵循等。
  2. 添加属性

    • Objective-C Extensions 可以添加新的实例变量和属性,但只能在类的实现文件中的类扩展部分做到这一点。
    • Swift Extensions 不能添加存储属性(即带有内存存储的属性),但可以添加新的计算属性。
  3. 方法添加

    • 在 Objective-C 中,添加新方法通常使用 Categories,而 Extensions 主要用于添加私有属性和私有方法。
    • Swift Extensions 可以添加新的实例方法和类型方法到现有类型。
  4. 位置和可见性

    • Objective-C Extensions 需要在类的主实现文件中定义,它们的作用一般是私有的。
    • Swift Extensions 可以在同一个项目的任何文件中定义,并且可以是私有的、公开的或者其他任何访问级别。
  5. 协议遵循

    • Objective-C 中,通常不使用 Extensions 来使类遵循协议。
    • Swift Extensions 经常被用来添加协议遵循,甚至可以在扩展中实现协议要求的方法。
  6. 类型修改

    • Objective-C Extensions 不能用于扩展其他类型,如结构体或枚举,因为 Objective-C 不支持这些类型。
    • Swift Extensions 可以用来扩展几乎所有类型,包括类、结构体、枚举和协议。
  7. 可扩展性

    • Objective-C 的扩展性主要受限于它的动态特性和 Category 的设计。
    • Swift 的设计更加现代和模块化,使得 Extensions 更加强大和灵活。
  8. OC extension和Swift extension加载时机:

    加载时机上实际上是一致的,因为它们都是在编译阶段被合并到类定义中的,而不是在运行时动态加载。以下是两者在加载时机上的具体描述:

    Objective-C Extensions(类扩展)

    Objective-C 的类扩展主要用于向类添加私有属性、方法或者实例变量。类扩展通常在类的实现文件(.m 文件)中声明,它们的成员(包括属性、方法等)在编译时会被合并到类的定义中。这意味着,当类被编译时,类扩展中声明的任何内容都会成为类的一部分,就像直接写在类的主体定义中一样。所以,它们的加载时机就是编译时。

    Swift Extensions

    Swift 的 Extensions 允许你为现有类型添加新的方法、计算属性、初始化器、下标、协议遵循等。和 Objective-C 的类扩展一样,Swift 的扩展在编译时就会被合并到被扩展的类型中。它们不会在运行时改变类型的布局或动态添加功能,而是在编译阶段就已经确定了。这意味着,Swift 扩展中的方法、计算属性等也是在编译时被集成到类型的定义中的。

    总结

    虽然 Objective-C 的类扩展和 Swift 的扩展用于不同的目的和有不同的功能,它们的加载时机都是在编译时,而不是运行时。这与 Objective-C 的 Categories 不同,后者确实在运行时动态添加新方法。Swift 的扩展和 Objective-C 的类扩展都是在编译时期就已经确定的,它们为现有类型提供了额外的功能,但不改变类型的内存布局。

总的来说,Swift 的 Extensions 提供了更多的功能和更大的灵活性。它们是 Swift 语言的一个核心特性,允许开发者以一种类型安全的方式来增强现有类型的功能,而不需要修改原始源代码或继承。Objective-C 的类扩展功能较为有限,主要用于添加私有属性和方法,以及在编译时向类中添加新的实例变量。

相关文章:

iOS Category

原理: 【iOS】——分类、扩展和关联对象_ios 为什么分类不能加成员变量-CSDN博客 面试题: 1.Category和Extension区别? 在 Objective-C 中,Category 和 Extension 是两种用于向现有类添加新功能的机制,但它们各有特…...

5.Sentinel入门与使用

5.Sentinel入门与使用 1.什么是 Sentinel?Sentinel 主要有以下几个功能: 2.为什么需要 Sentinel?3.Sentinel 基本概念3.1 什么是流量控制?3.1.1 常见流量控制算法3.1.2 Sentinel 流量控制流控效果介绍如下: 3.2 什么是熔断?熔断策略 3.3 Sentinel 组成(资源和规…...

上位机图像处理和嵌入式模块部署(h750 mcu和图像处理)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 前面我们说过,h750和之前的103、407相比较,本身cpu频率比较高,flash大小一般,但是ram比较大&#x…...

信创服务器操作系统的适配迁移分析

浅谈信创服务器操作系统的适配迁移 01 服务器操作系统迁移适配流程复杂 随着CentOS停服临近和红帽RHEL源码权限受限,服务器操作系统安全漏洞风险加剧。国内众多企业面临CentOS、REHL等系统升级替换的挑战。同时,出于安全、功能升级和合规需求&#xff0…...

在Ubuntu 20.04上安装和配置MySQL 8:详细指南和远程访问设置

目录 一、MySQL 8的特点和优势 二、在Ubuntu 20.04上安装MySQL 8 三、初始化MySQL 四、配置MySQL远程访问 五、 创建远程访问用户 六. 配置防火墙 七、 测试远程访问 总结 MySQL是一种开源的关系型数据库管理系统,被广泛应用于各种应用程序和网站中。MySQL …...

Vue43-单文件组件

一、脚手架的作用 单文件组件:xxx.vue,浏览器不能直接运行!!! 脚手架去调用webpack等第三方工具。 二、vue文件的命名规则 建议用下面的两种方式。(首字母大写!!!&#x…...

如何快速使用向量检索服务DashVector?

免费体验阿里云高性能向量检索服务:https://www.aliyun.com/product/ai/dashvector 本文将介绍如何快速上手使用向量检索服务DashVector。 前提条件 已创建Cluster:创建Cluster。 已获得API-KEY:API-KEY管理。 已安装最新版SDK&#xff1a…...

Linux 用户和用户组 创建用户 创建组

介绍 一个组有多个用户,可以给组分配权限,那么该组的使用用户都有该组的权限,就不用一个个分配,而且很好管理。 创建用户组 groupadd 组名删除用户组 groupdel test查看用户所属组 id [用户名]修改用户组 把abc用户添加到m…...

Character Animator 2024 mac/win版:赋予角色生命,动画更传神

Character Animator 2024是一款强大的角色动画制作软件,以其创新的功能和卓越的性能,为动画师、游戏开发者以及设计师们带来了全新的创作体验。 Character Animator 2024 mac/win版获取 这款软件采用了先进的骨骼绑定技术,使得角色动画的制作…...

短剧app广告变现模式开发

短剧app搭建是一个涉及多个方面的复杂过程,下面将介绍主要的步骤和考虑因素: 明确目标和定位:在开始搭建之前,首先要明确你的目标受众是谁,以及短剧app的主要定位是什么。这有助于在后续的开发过程中更有针对性地进行…...

如何选择适合的编程语言入门?

推荐学习网站:offernow.cn 如何选择最适合自己的编程语言呢?接下来,我给大家分享一些实用的建议,希望能帮到你们。 一、明确目标和兴趣 考虑你的兴趣和未来方向是选择编程语言的首要因素。如果你对网页开发感兴趣,可以…...

Spring Boot入门教程

Spring Boot入门教程可以按照以下步骤进行,以确保清晰和有条理地学习: 1. Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,旨在简化Spring应用的初始搭建以及开发过程。它使用了特定的方式来进行配置,使开发人员不再…...

芝麻文件重命名 一键批量重命名 支持批量修改图片 文档 文件夹名称

芝麻文件重命名是一款专业的文件批量重命名软件,它提供了丰富的功能和灵活的命名规则,可以大大提高文件管理的效率。以下是关于芝麻文件重命名的详细介绍: 一、软件特点 支持批量重命名:芝麻文件重命名支持文件和文件夹的批量重命…...

docker守护进程配置代理

一:配置 Docker 守护进程使用代理 1.创建或编辑 Docker 配置文件目录 2.创建或编辑代理配置文件 3.重新加载系统守护进程并重启 Docker 4.验证代理设置 5.使用 docker pull 拉取镜像,验证代理设置 步骤 1:创建或编辑 Docker 配置文件目录 Doc…...

使用Minikube部署Kubernetes环境

使用Minikube部署Kubernetes环境 1. Minikube简介 Minikube是一个轻量级的Kubernetes实现,它在本地运行一个Kubernetes集群,可以是单节点或者集群环境,主要用于开发和测试。Minikube支持Kubernetes的所有主要功能,包括Dashboard…...

蚂蚁集团:2023年科研投入211.9亿元

6月13日,蚂蚁集团发布2023年可持续发展报告。报告显示,2023年蚂蚁集团科研投入达到211.9亿元,再创历史新高,蚂蚁科技投入的重点是人工智能和数据要素技术。 蚂蚁集团董事长兼CEO井贤栋在报告致辞中说,面向未来&#x…...

pikachu靶场之XSS漏洞测试

一、环境配置 1.pikachu官网下载 下载地址:https://github.com/zhuifengshaonianhanlu/pikachu 2.百度网盘(里面含有pikachu跟phpstudy) 链接:pikachu下载 密码:abcd 配置:pikachu下载及安装-图文详解…...

python快速入门之Flask框架

文章目录 一、pip安装二、接口开发三、测试 一、pip安装 pip install flask 二、接口开发 from flask import Flaskapp Flask(__name__)app.route("/test") def index():return "test"if __name__ __main__:app.run()三、测试 http://127.0.0.1:5000…...

【云原生| K8S系列】Kubernetes Daemonset,全面指南

Kubernetes中的DaemonSet是什么? Kubernetes是一个分布式系统,Kubernetes平台管理员应该有一些功能可以在所有节点上运行特定于平台的应用程序。例如,在所有Kubernetes节点上运行日志代理。 这就是Daemonset发挥作用的地方。 Daemonset是一个原生的K…...

【Python机器学习实战】 | 基于决策树的药物研究分类预测

🎩 欢迎来到技术探索的奇幻世界👨‍💻 📜 个人主页:一伦明悦-CSDN博客 ✍🏻 作者简介: C软件开发、Python机器学习爱好者 🗣️ 互动与支持:💬评论 &…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...

【JavaEE】-- HTTP

1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...

逻辑回归暴力训练预测金融欺诈

简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...

阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)

cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...

前端调试HTTP状态码

1xx(信息类状态码) 这类状态码表示临时响应,需要客户端继续处理请求。 100 Continue 服务器已收到请求的初始部分,客户端应继续发送剩余部分。 2xx(成功类状态码) 表示请求已成功被服务器接收、理解并处…...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年,金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征: AI驱动的自适应攻击:攻击流量模拟真实用户行为,差异率低至0.5%,传统规则引…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...