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 的类扩展功能较为有限,主要用于添加私有属性和方法,以及在编译时向类中添加新的实例变量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/30021.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

反激开关电源输入电解电容选型及计算

输入电解电容波形如下 计算 1、输入电解电容经验选取法 当输入电压为220V20%(AC176-264V)时 按照输出功率选取:W/μF 耐压(400V,输入176-264V最高DC峰值373V) 当输入电压为11020%时(AC88-132V…

windows服务器一台机器安装多个mysql实例

1、复制安装mysql安装包 2、修改配置文件信息 标注红色部分是需要修改成复制后的包信息 [mysqld] default-time_zone8:00basedirD:/tools/MySQL-Cluster/mysql-53306 datadirD:/tools/MySQL-Cluster/mysql-53306/data default-storage-engineINNODB sql-mode"STRICT_TRANS…

网络运维:企业数字化转型的基石

在数字化时代,网络已经成为企业运营不可或缺的一部分。网络运维作为确保网络稳定、安全和高效运行的关键环节,其重要性不言而喻。本文将探讨网络运维的重要性,并分析其在企业数字化转型中的作用。 网络运维的定义 网络运维,也称…

Amazon Systems Manager中补丁合规性定期扫描

问题 需要使用Amazon Systems Manager对EC2补丁合规性定期扫描。 步骤 点击如下入口界面: 权限使用默认配置,勾选“Scan instances for missing patches daily”每天扫描EC2实例是否存在补丁,来完成合规检查,选择所有实例&…

Zabbix自定义监控JAVA进程

一.定义脚本 二 .ZABBIX得agent允许以root身份执行 三. Zabbix测试自定item是否成功 四.ZABBIX服务端web添加新得item项 五.查看最新数据,取值成功

每日AI资讯-20240618

1. 3D 版 SORA 来了! DreamTech 官宣了其高质量 3D 生成大模型 Direct3D,并公开了相关学术论文 Direct3D: Scalable Image-to-3D Generation via 3D Latent Diffusion Transformer。 链接:https://arxiv.org/abs/2405.14832 这是首个公开发布…

分享一下,如何搭建个人网站的步骤

在这段充满探索与创造的奇妙旅途中,我就像一位耐心的建筑师,在数字世界的荒原上精心雕琢,两周的时光缓缓流淌。每天,我与代码共舞,手执HTML、CSS与JavaScript这三大构建魔杖,一砖一瓦地筑起了梦想中的网络城…

JDK与JRE与JVM:它们之间的区别

JDK与JRE与JVM:它们之间的区别 JDK(Java开发工具包) JDK是JRE的超集,它包含JRE所拥有的一切以及编译器、调试器等开发工具。 JDK代表Java开发工具包。要在您的系统上安装Java,您需要首先在系统上安装JDK。 JDK包含编…

Blazor 中基于角色的授权

介绍 Blazor用于使用 .NET 代码库创建交互式客户端 Web UI。Microsoft 默认在 Blazor 应用程序中提供了一个用于身份验证和授权的身份框架。请注意,他们目前使用 MVC Core Razor 页面作为身份验证 UI。使用“Microsoft.AspNetCore.Identity.UI”包库来实现这一点。…

实战|YOLOv10 自定义目标检测

引言 YOLOv10[1] 概述和使用自定义数据训练模型 概述 由清华大学的研究团队基于 Ultralytics Python 包研发的 YOLOv10,通过优化模型结构并去除非极大值抑制(NMS)环节,提出了一种创新的实时目标检测技术。这些改进不仅实现了行业领…

基于STM32和人工智能的智能楼宇安防系统

目录 引言环境准备智能楼宇安防系统基础代码实现:实现智能楼宇安防系统 4.1 数据采集模块4.2 数据处理与分析4.3 控制系统4.4 用户界面与数据可视化应用场景:智能楼宇安防管理与优化问题解决方案与优化收尾与总结 1. 引言 随着物联网和人工智能技术的…

考研数学|做完《660》,做《880》还是吃力,怎么办?

880吃力说明基础还是不太扎实,建议配合知能行再刷880。 强化之前做660,然后在强化的时候再做880。 660整体难度属于基础阶段到强化阶段。而且是选填部分的题目,所以还是要做一些其他题 然后说一下推荐的习题册:基础不好先做1800、…

公司电脑加密软件——【中科数安】电脑文件资料透明加密,防泄密系统

中科数安电脑文件资料透明加密防泄密系统介绍 中科数安提供的电脑文件资料透明加密防泄密系统,是一款专为企业电脑终端设计的数据安全解决方案。该系统通过采用先进的透明加密技术和精细化的权限管理,旨在全方位保护公司电脑中存储、处理、传输的各类文…

在同一个 Blazor 应用中结合 SQL-DB 和 MongoDB

介绍 传统上,在单应用程序中,我们对整个应用程序使用单个数据库服务器。但是,我将 SQL 数据库和 MongoDB 结合在同一个应用程序中。此应用程序将是 RDBMS 和 No SQL 数据库的组合。我们将从头开始创建一个 Blazor 应用程序,并使用…

APS计划排程系统如何打破装备使用约束

APS计划排程系统是离散制造型企业在计划控制方向的重要支撑,它提供的是交期预测、订单排产计划、物料采购计划、人力分配计划等等。近些几年来,多品种、小批量、多订单的生产模式,让企业的计划员应接不暇、疲累不堪,传统的人工经验…

C++语法01 基本框架

目录 什么是 C ? 新建源程序 保存源程序 程序基本框架 #include using namespace std; int main() return 0; 编译 运行 什么是 C ? C语言,是基本的程序设计语言之一【程序设计语言,简单的来说就是编写代码来操控计…

数据库大作业——音乐平台数据库管理系统

W...Y的主页😊 代码仓库分享💕 《数据库系统》课程设计 :流行音乐管理平台数据库系统(本数据库大作业使用软件sql server、dreamweaver、power designer) 目录 系统需求设计 数据库概念结构设计 实体分析 属性分…

PostgreSQL查看表的大小

PostgreSQL查看表的大小 在 PostgreSQL 中,可以使用一系列函数和系统视图来查看表的大小。这些工具可以帮助您获取表的基本存储大小、包括索引和 TOAST 的总大小等信息。下列方法演示了如何获取这些信息。 使用函数查看表的大小 pg_relation_size():返…

Effective Python

列表与字典 键不在字典 contour counters.get(key,0); 键不在字典,返回默认0. names votes.setdefault(key,[]);键不在字典,关联插入默认值后,返回默认[].

AWS CloudFront怎么计费的?

AWS CloudFront是Amazon Web Services提供的一项内容分发网络(CDN)服务,旨在加快网站、应用程序、视频流和其他Web内容的全球分发速度。通过在全球范围内缓存内容至边缘位置,CloudFront能够减少延迟,提高用户体验。关于CloudFront的计费方式&…