探索Objective-C中的对象复制:深入理解copy和mutableCopy

NSString为什么copy修饰?深拷贝和浅拷贝的区别?NSMutableArray进行copy是深拷贝还是浅拷贝?NSMutablearray里的内容如果是NSString,那么mutablecopy的话是拷贝的内容还是内容地址都拷贝?NSArray的内容是OC对象还是其他的对象,是否可以是非OC对象?nsarray存储的是内容还是地址?下面针对上面的问题一一分析。

首先,让我们引用阳神Sunny博客中的一道面试题作为引子:

这个问题揭示了深入了解copy的重要性。那么,copy究竟是什么,它又有何用途呢?接下来,我们将一起探索copy的奥秘。

  1. Copy和mutableCopy方法

在Objective-C中,copy和mutableCopy是对象特有的方法,它们在NSObject类及其子类中都有定义。此外,还存在对应的类方法copyWithZone:,其参数为一个结构体指针,用于指定内存区域。同时,为了支持这些方法,NSCopying和NSMutableCopying两个协议也被引入。

1.1 ◆ copy方法定义与特性和类方法的区别

首先,我们来看copy和mutableCopy在Objective-C中的重要性。其中,+copy:和+copyWithZone:这两个方法,主要是为了确保"类"对象也能遵循NSCopying协议,从而能够作为键值对插入NSDictionary中。由于类对象在全局范围内只能存在一份,因此这两个方法实际上只是简单地返回self。值得注意的是,这两个方法在ARC(自动引用计数)环境下是不可用的。

另一方面,-copy和-mutableCopy这两个方法在调用时,会创建一个新的副本对象,并直接返回-copyWithZone:和-mutableCopyWithZone:方法的结果。

1.2 ◆ copy协议与实现

为了实现这些方法,对象需要遵循特定的协议。常见的NSString、NSArray、NSDictionary等类都已经遵守了这些协议,因此它们可以在需要时生成副本对象。然而,NSObject类本身并未实现-copyWithZone:和-mutableCopyWithZone:这两个方法,因此,若子类对象需要使用-copy和-mutableCopy,则必须实现NSCopying和NSMutableCopying这两个协议。

1.3 ◆ NSZone的历史背景和弃用情况

关于NSZone,它已被Apple弃用,因此我们无需深入探讨。

  1. 拷贝的意义和深浅拷贝解析
2.1 ◆ 拷贝的核心意义

拷贝,字面意思即为拷贝或克隆,其核心目的在于复制出一份与原内容完全一致的新内容。通过拷贝,我们可以实现对原内容的独立操作,从而确保在改变副本时不会影响到原内容,反之亦然。

2.2 ◆ 深拷贝与浅拷贝

接下来,我们通过具体示例来讲解容器和非容器对象的拷贝方式。其中,深拷贝与浅拷贝有以下不同点:

  1. 浅拷贝(或称为指针拷贝):仅复制对象的引用,不会生成新对象。

  2. 深拷贝(或称为对象拷贝):真正创建一个新的对象,并将其原始数据复制进去。

  3. 具体对象的拷贝分析

3.1 ◆ 非容器对象的拷贝分析

首先,我们来看NSString和NSMutableString这两种非容器对象。在处理这两种对象时,拷贝的意义主要体现在对原始对象的保护上。通过拷贝,我们可以获得原始对象的一个独立副本,从而在不影响原始对象的基础上进行各种操作。这种拷贝方式通常被称为浅拷贝。

3.2 ◆ 容器对象的深层拷贝探讨与实现

接下来,我们转向NSArray和NSMutableArray这两种容器对象。与非容器对象不同,容器对象的拷贝涉及到更复杂的操作。为了确保在改变副本时不会影响到原内容,我们需要进行深层次的拷贝。这种深拷贝方式会递归地复制容器对象中的所有元素,从而生成一个与原容器对象完全独立的新容器对象。

我们发现,即使在多次执行copy操作时,容器对象仍会生成新的对象,这是因为必须避免影响原始内容。

3.3 ◆ 容器对象的内存管理和优化

为了实现真正的元素对象拷贝,可以通过归档技术来达成

  1. 对象复制的总结
4.1 ◆ 浅拷贝与深拷贝的关键点

在对象复制方面,存在浅拷贝与深拷贝的两种方式。理解这两种拷贝方式的关键在于把握其目的:确保原始内容与副本相互独立,互不影响。

4.2 ◆ 内存管理和copy属性的使用

在内存管理上,浅拷贝不会生成新对象,但会进行retain操作以保持其存活。而深拷贝则会创建新对象。此外,使用copy属性而非property的原因也在于此,以确保在修改副本时不会影响原始内容。

  1. 内存管理的区别与总结
5.1 ◆ MRC与ARC中的retain与strong比较

MRC和ARC环境下,我们分别使用retain和strong来修饰对象。然而,在某些情况下,为了防止对象被意外释放,我们需要通过copy来进行属性设置。

5.2 ◆ 现代开发习惯和建议

尽管在ARC时代,使用strong和copy都能达到类似的效果,但主要还是基于习惯。当然,行业中的一些推荐和经验值得我们参考,例如通过将strong替换为copy来避免潜在的循环引用问题。

5.3 ◆ 远程控制的尝试与思考

今天尝试通过屏幕共享功能来远程控制其他Mac时,也让我思考到用户体验和便捷性的重要性。最终选择QQ的远程功能,因为它简单而高效。这启发我们在功能设计时应注重用户体验,使用户能够更便捷地操作。

相关推荐
Scott9999HH31 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
2501_916008892 小时前
iOS应用开发工具全面解析:如何选择与优化开发效率
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
a4493153622 小时前
iPhone Face ID 故障的分层诊断——原深感系统与主板加密配对机制
macos·ios·电脑·cocoa·iphone
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
白玉cfc3 小时前
【iOS】内存五大分区
macos·ios·cocoa
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区5 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大5 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf