Objective-C中的copy协议
NSObject对象是否可以copy自己
NSObject类没有实现NSCopying或者NSMutableCopying协议,但是却有copy以及mutableCopy实例方法。然而,如果用NSObject对象直接调用其copy或者mutableCopy方法,会报错。也就是说,NSObject对象无法copy自己。
既然NSObject类没有实现copy协议,那为什么还要有对应的copy和mutableCopy方法呢?
因为NSObject类的copy和mutableCopy方法里面分别都会调用copyWithZone以及mutableCopyWithZone,那么所有继承自NSObject类并且实现NSCopying或者NSMutableCopying协议的类的拷贝行为,都可以简化为调用copy或者mutableCopy方法。
实现copy协议时,何时需要调用[super copyWithZone:zone]
1 类直接继承自NSObject,无需调用[super copyWithZone:zone]
@interface X : NSObject <NSCopying>
@property (assign, nonatomic) NSInteger i;
@end
@implementation X
- (id)copyWithZone:(NSZone *)zone {
X *x = [[[self class] alloc] init]; //没有调用[super copyWithZone:zone]
x.i = self.i;
return x;
}
类X直接继承自NSObject,由于NSObject没有实现copy协议,因此如果调用[super copyWithZone:zone]编译器会报错:
No visible @interface for 'NSObject' declares the selector 'copyWithZone:'
2 父类实现了copy协议,子类也实现了copy协议,子类需要调用[super copyWithZone:zone]
@interface Y : X <NSCopying>
@property (assign, nonatomic) NSInteger j;
@end
@implementation Y
- (id)copyWithZone:(NSZone *)zone {
Y *y = [super copyWithZone:zone]; //子类调用[super copyWithZone:zone]
y.j = self.j;
return y;
}
@end
子类通过调用[super copyWithZone:zone]方法来分配内存,并且拷贝父类中的实例变量,子类自己的实例变量需要自己拷贝
3 父类没有实现copy协议,子类实现了copy协议,子类无需调用[super copyWithZone:zone]
如果上面的例子中类X没有实现copy协议,而子类Y实现了copy协议,这种情况类似与情形1,子类Y无需调用[super copyWithZone:zone]
- (id)copyWithZone:(NSZone *)zone {
Y *y = [[[self class] alloc] init]; //子类无需调用[super copyWithZone:zone]
y.i = self.i;
y.j = self.j;
return y;
}
但是这种时候子类需要自己copy父类中的实例变量。
为何在copyWithZone方法中要调用[[[self class] alloc] init]来分配内存
在上面的情形2中,子类Y继承子父类X,如果父类X的copyWithZone方法使用:
[[X alloc] init];
来分配内存,那么在子类Y copy的时候就会出现内存分配的问题。
因为在子类Y的copyWithZone的方法里面调用会调用父类[super copyWithZone:zone]方法,而父类中[[X alloc] init]创建的对象分配的内存大小和类X的实例一样大,而这里是要拷贝Y,类Y继承了X的实例变量,同时也有自己的实例变量,所以类Y的实例所占用的内存明显比类X的实例大,因此,这里会导致内存分配错误。而父类X中如果使用[[[self class] alloc] init]来创建对象分配内存,在运行时self class就是类Y,这样保证了内存分配正确。
propery中的copy属性
这里只需记住,property的copy只会产生copyWithZone的调用,而不会产生mutableCopyWithZone的调用。
Objective-C中的copy协议的更多相关文章
- OC中的copy
copy的概念 Copy的字面意思是"复制"."拷贝",是一个产生副本的过程 对象拷贝的目的:要使用某个对象的数据,但是在修改对象的时候不影响原来的对象内容,常 ...
- 理解Objective C 中id
什么是id,与void *的区别 id在Objective C中是一个类型,一个complier所认可的Objective C类型,跟void *是不一样的,比如一个 id userName, 和vo ...
- 浅谈Objective—C中的面向对象特性
Objective-C世界中的面向对象程序设计 面向对象称程序设计可能是现在最常用的程序设计模式.如何开发实际的程序是存在两个派系的-- 面向对象语言--在过去的几十年中,很多的面向对象语言被发明出来 ...
- Android 中多点触摸协议
http://blog.csdn.net/zuosifengli/article/details/7398661 Android 中多点触摸协议: 参考: http://www.kernel.org/ ...
- C# WCF学习笔记(二)终结点地址与WCF寻址(Endpoint Address and WCF Addressing) WCF中的传输协议
URI的全称是 Uniform Rosource Identifire(统一资源标识),它唯一标识一个确定的网绐资源,同时也表示资源所处的位置及访问的方式(资源访问所用的网络协议). 对于Endpoi ...
- 详解Objective-C中委托和协议
Objective-C委托和协议本没有任何关系,协议如前所述,就是起到C++中纯虚类的作用,对于“委托”则和协议没有关系,只是我们经常利用协议还实现委托的机制,其实不用协议也完全可以实现委托. AD: ...
- c#中命令copy已退出,返回值为1
c#中命令copy已退出,返回值为1 本正经的道:董姐刚才你说的修心养性其中的'修心'我 有孕在身刚好由戴梦瑶顶替了她的位置按照的指示 ╋旆呆 湎术葶页 邾箕砜笳 烦璜卿廑 奶奶个腿儿的等下次非让你 ...
- PHP中的http协议
PHP中的http协议 http协议基本组成 报文:用于Http协议交互的信息 请求行:包括请求的方法,URL和HTTP协议版本 状态行:包括响应结果的状态码,状态描述和Http版本 首部字段:包括请 ...
- Dockerfile 中的 COPY 与 ADD 命令
Dockerfile 中提供了两个非常相似的命令 COPY 和 ADD,本文尝试解释这两个命令的基本功能,以及其异同点,然后总结其各自适合的应用场景. Build 上下文的概念 在使用 docker ...
随机推荐
- PHP中检测ajax请求的代码例子
多数情况下,基于JavaScript 的Js框架如jquery.Mootools.Prototype等,在发出Ajax请求指令时,都会发送额外的 HTTP_X_REQUESTED_WITH 头部信息, ...
- Android使用百度地图定位
下面事例是使用Android平台的部分代码.对于这个平台百度的开放人员已经写了完整的demo,把工程导入到eclipse中之后一般没有错误,如果报错的话,eclipse也会给出提示.一般可以通过将pr ...
- Xamarin Add Mac
右键IOS项目,设置为启动项目,点击启动(F5)弹出如下提示 提示开启远程访问权限,按照提示照做即可 在mac端 进入系统偏好设置 双击选择共享 打开远程登陆,允许所有用户访问 设置完成后点击ok 弹 ...
- 【笔试&面试】C#中的程序集
1. C#中的程序集(Assembly) 答:程序集是包含一个或多个类型定义文件和资源文件的集合.它允许我们分离可重用类型的逻辑表示和物理表示. 程序集是一个可重用.可实施版本策略和安全策略 ...
- MongoVUE简单操作手册
本文转自网络,对疑问的地方做了修改 官方参考文献:http://www.mongovue.com/tutorials/ MongoVUE 是个比较好用的MongoDB客户端,需要注册,但是可以变成永久 ...
- Mac下Sublime Text 3安装配置
1.下载Sublime Text 3 2.安装Package Control,参考 快捷键 control + ` 或者菜单栏选择View > Show Console 在控制台输入: impo ...
- 鹿定制|Lu Couture|鹿定制·高级西装礼服私享定制品牌|芙蓉中路明城国际1425
鹿定制|Lu Couture|鹿定制·高级西装礼服私享定制品牌|芙蓉中路明城国际1425 联系我们
- javascript中this、apply、call、bind的用法和区别
参考阮一峰文章链接:http://javascript.ruanyifeng.com/oop/basic.html#toc10
- java 存储oracle的clob字段
项目中有很长的字符创需要存储,用到了oracle的clob字段,直接很长的字符串插入到clob字段中会报字符过长的异常,于是便寻求解决方案.看到这个博客写的还不错 首先,创建一个含CLOB字段的表: ...
- DS18B20
DS18B20驱动 [ 2012-5-14 12:01:00 | By: 吴师傅 ] 14 推荐 一.概述 DS18B20是一种单总线数字温度传感器.測试温度范围-55℃-125℃,温度数据位可配 ...