典型 cloning, copy, copyWithZone:, NSCopyObject()
来源:互联网 发布:君子知怕行文思路 编辑:程序博客网 时间:2024/06/11 10:25
转自: http://hi.baidu.com/yezehui2002/blog/item/8c328299f0c3631e6e068c8b.html
在 C++ 中,定义复制运算符和相关的操作是很重要的。在 Objective-C 中,运算法是不允许重定义的,所能做的就是要求提供一个正确的复制函数。
克隆操作在 Cocoa 中要求使用 NSCopying 协议实现。该协议要求一个实现函数:
这个函数的参数是一个内存区,用于指明需要复制那一块内存。Cocoa 允许使用不同的自定义区块。大多数时候默认的区块就已经足够,没必要每次都单独指定。幸运的是,NSObject 有一个函数
封装了 copyWithZone:,直接使用默认的区块作为参数。但它实际相当于 NSCopying 所要求的函数。另外,NSCopyObject() 提供一个不同的实现,更简单但同样也需要注意。下面的代码没有考虑 NSCopyObject():
注意,我们使用的是 allocWithZone: 而不是 alloc。alloc 实际上封装了 allocWithZone:,它传进的是默认的 zone。但是,我们应该注意父类的 copyWithZone: 的实现。
NSCopyObject()
NSObject 事实上并没有实现 NSCopying 协议(注意函数的原型不同),因此我们不能简单地使用 [super copy...] 这样的调用,而是类似 [[... alloc] init] 这种标准调用。NSCopyObject() 允许更简单的代码,但是需要注意指针变量(包括对象)。这个函数创建一个对象的二进制格式的拷贝,其原型是:
二进制复制可以复制非指针对象,但是对于指针对象,需要时刻记住它会创建一个指针所指向的数据的新的引用。通常的做法是在复制完之后重置指针。
Dummy-cloning, mutability, mutableCopy and mutableCopyWithZone:
如果需要复制不可改变对象,一个基本的优化是假装它被复制了,实际上是返回一个原始对象的引用。从这点上可以区分可变对象与不可变对象。
不可变对象的实例数据不能被修改,只有初始化过程能够给一个合法值。在这种情况下,使用“伪克隆”返回一个原始对象的引用就可以了,因为它本身和它的复制品都不能够被修改。此时,copyWithZone: 的一个比较好的实现是:
retain 操作意味着将其引用加 1。我们需要这么做,因为当原始对象被删除时,我们还会持有一个复制品的引用。
“伪克隆”并不是无关紧要的优化。创建一个新的对象需要进行内存分配,相对来说这是一个比较耗时的操作,如果可能的话应该注意避免这种情况。这就是为什么需要区别可变对象和不可变对象。因为不可变对象可以在复制操作上做文章。我们可以首先创建一个不可变类,然后再继承这个类增加可变操作。Cocoa 中很多类都是这么实现的,比如 NSMutableString 是 NSString 的子类;NSMutableArray 是 NSArray 的子类;NSMutableData 是 NSData 的子类。
然而根据我们上面描述的内容,似乎无法从不可变对象安全地获取一个完全的克隆,因为不可变对象只能“伪克隆”自己。这个限制大大降低了不可变对象的可用性,因为它们从“真实的世界”隔离了出来。
除了 NSCopy 协议,还有一个另外的 NSMutableCopying 协议,其原型如下:
mutableCopyWithZone: 必须返回一个可变的克隆,其修改不能影响到原始对象。类似 NSObject 的 copy 函数,也有一个 mutableCopy 函数使用默认区块封装了这个操作。mutableCopyWithZone: 的实现类似前面的 copyWithZone: 的代码:
不要忘记我们可以使用父类的 mutableCopyWithZone:
- 典型 cloning, copy, copyWithZone:, NSCopyObject()
- Copy Constructor versus Cloning
- NSCopyObject
- NSCopyObject
- Cloning
- Deep Copy in C# (Cloning for a user defined class)
- iOS-Bug: copyWithZone:
- -(id)copyWithZone:(NSZone *)zone
- OC--copyWithZone:(NSZone *)zone
- Implementing NSCopying (or NSCopyObject() considered harmful)
- Cloning a Windows Database
- Binary Cloning 安装ORACLE
- Gamebryo—Cloning Internals
- Cloning.JAVA源码
- IOS,[UILabel copyWithZone:]: 的解决方法
- Cloning public code: An example
- Seamless cloning泊松克隆
- Seamless cloning泊松克隆
- 移位运算符学习
- 应对Google企鹅更新的一点思路
- VB.NET调用Windows API函数 方法 (实例)
- Linux内核bridge浅析
- 一个关于PC机通信软件设计
- 典型 cloning, copy, copyWithZone:, NSCopyObject()
- VBS DateAdd 方法
- FTP文件上传与下载
- 电子签名公司Docusign融资$4750万 互联网女皇坐镇董事会
- Unity3d开发概述
- CSDN博客积分规则和获取积分方法
- VB.NET调用Windows API函数(整理中)
- Reporting Service RDLC报表如何获取 矩阵本表中的某一列的值
- C++基础:C++的结构struct