copy|mutablecopy 小述
来源:互联网 发布:编程算法看不懂 编辑:程序博客网 时间:2024/04/29 21:12
copy 和 mutablecopy 到底是怎么回事儿?
原则其实还是这样:所有的设计都是为了功能方便!这两个方法的实现意义大概在两个点:
添加这两个方法,实现了NSString,NSArray 等OC基本数据类型的拷贝操作。
提供一套代理协议模式的设计应用,保留了一套方便的接口,方便用户自定义OC对象拷贝的实现。
1. 先看Foundation 框架下NSObject.h文件中声明了两个协议:NSCopying和 NSMutableCopying
/*************** Basic protocols***************/
@protocol NSCopying
- (id)copyWithZone:(nullableNSZone *)zone;
@end
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(nullableNSZone *)zone;
@end
(1). 其实在真实的开发中,一般来说,真正添加这两个协议来实现拷贝的对象的需求可能不多!而我们最常用的基本OC对象(字符串,数组,集合,字典,NSData ,NSURL,NSIndeSet 等)默认是遵循实现了两个协议或其中一个协议的。看看NSString和 NSArray头文件就知道了:
@interface NSString :NSObject <NSCopying,NSMutableCopying, NSSecureCoding>
@interface NSArray :NSObject <NSCopying,NSMutableCopying, NSSecureCoding, NSFastEnumeration>
…………
(2). 和NSString、NSArray一样,一个自定义对象实现拷贝功能,所依赖的方法是copy和这mutablecopy,那么久必须—>对应的拷贝对象(NSObject的子类)需要遵循以上两个协议(<NSCopying,NSMutableCopying>)。由此可知,代理模式在OC的语言设计中真的是无处不在呀!
…………
(3). 注意,就算是自定义对象MyObj 遵循了协议,实现协议方法(copyWithZone:| mutableCopyWithZone:)确实要靠自己来写,最后的效果就是以coder的意志做转移的了。但是最好不要这么任性,该copy的还是copy一个给返回,该mutable copy的mutablecopy一份返回,体现这一点可以通过亲自测试,看第二条
2. 以NSString和 NSArray为例看看效果, 从而知道copy 和mutablecopy在实际使用中的效果。
NSMutableString *str = [NSMutableStringstringWithString:@"123"];
NSString *strCopy = [strcopy]; ///返回不可变,
NSMutableString *mustrCopy = [strmutableCopy]; ///返回可变
NSLog(@"\n%p->%@, %p->%@, %p->%@",&str,str,&strCopy,strCopy,&mustrCopy,mustrCopy);
// 0x7fff5fbff7d8->123, 0x7fff5fbff7d0->123, 0x7fff5fbff7c8->123
[mustrCopy appendString:@"z"];
str =(NSMutableString *)@"321"; /// 注意,和C语言不一样,@出来的东西可是对象,不能实现强转!str将成为不可变。
// [str appendString:@"a"]; /// 崩溃,原因就是这里(NSMutableString *)不是强转,
str = [NSMutableStringstringWithFormat:@"321"];
[str appendString:@"a"];
[[mustrCopy copy]appendString:@"a"];/// 崩溃,[mustrCopy copy]得到的是不可变字符串
NSMutableArray *muArr = [NSMutableArrayarrayWithObjects:str,strCopy,mustrCopy,nil];
NSArray *arrCopy = [muArrcopy];
NSMutableArray *muArrCopy = [arrCopymutableCopy];
NSLog(@"\n%p->%@, %p->%@, %p->%@",&muArr,muArr[0],&arrCopy,arrCopy[1],&muArrCopy,muArrCopy[2]);
// 0x7fff5fbff7c0->321a, 0x7fff5fbff7b8->123, 0x7fff5fbff7b0->123z
[muArr[0] appendString:@"b"];
[muArrCopy[2] appendString:@"y"];
NSLog(@"\n%p->%@, %p->%@, %p->%@",&muArr,muArr[0],&arrCopy,arrCopy[1],&muArrCopy,muArrCopy[2]);
NSLog(@"\n%p->%@, %p->%@, %p->%@",&str,str,&strCopy,strCopy,&mustrCopy,mustrCopy);
// 0x7fff5fbff788->321ab, 0x7fff5fbff780->123, 0x7fff5fbff778->123zy
// 0x7fff5fbff7a0->321ab, 0x7fff5fbff798->123, 0x7fff5fbff790->123zy
strCopy = @"UHB";
[mustrCopy appendString:@"YGV"];
NSLog(@"\n%p->%@, %p->%@, %p->%@",&muArr,muArr[0],&arrCopy,arrCopy[1],&muArrCopy,muArrCopy[2]);
NSLog(@"\n%p->%@, %p->%@, %p->%@",&str,str,&strCopy,strCopy,&mustrCopy,mustrCopy);
// 0x7fff5fbff788->321ab, 0x7fff5fbff780->123, 0x7fff5fbff778->123zyYGV
// 0x7fff5fbff7a0->321ab, 0x7fff5fbff798->UHB, 0x7fff5fbff790->123zyYGV
这个地方可以看出,数组中的可变字符串其实并没有copy新建,而是指向原始可变字符串。
(1) . 只看copy 和 mutablecopy,就我个人目前的意识来看,在OC基本对象数据类型中比较有意义,毕竟一切都是为了方便使用嘛! 对于这些OC基本类型,对于存在mutable和imutable的, copy 和mutablecopy的意义就特别明显了。不过其中存在一些注意点:
a. copy 和 mutablecopy都是创建了一个新的对象,copy的不可变,mutablecopy的可变。
b. 对于数组,数组中的成员如果是可变的,则是原有对象指针拷贝,如果是不可变的,则是内容拷贝。字典同理
c. copy 和 mutablecopy 如果是使用于OC的基本对象数据类型的时候,规律是恒定的。基本如上,可以将NSString理解为最原子的对象。
(2). 上面是讨论OC的基本对象数据类型,线面 新建一个 Person类,看看自定义的对象如何使用 copy 和 mutablecopy 。
@interface Person :NSObject<NSCopying,NSMutableCopying>
@property (nonatomic,strong) NSString *name;
@property (nonatomic,assign) NSInteger age;
@property (nonatomic,strong) NSString *title;
@end
@implementation Person
- (NSString *)description
{
return [NSStringstringWithFormat:@"name: %@, age: %ld, title: %@",_name,(long)_age,_title];
}
- (id)copyWithZone:(NSZone *)zone
{
Person *person = [Personnew];
person.age =self.age;
person.name =self.name;
person.title =self.title;
return person;
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
// mutablecopy 的处理方法,全由意志处理并不好!
// zone 这是一个表示管理内存的标示,且不管它
returnself;
}
@end
Person *_person = [[Personalloc] init];
Person *_personCopy = _person;
[_person setValuesForKeysWithDictionary:@{
@"name" : @"小名",
@"age" : @26,
@"title" : @"CEO"
}];
NSLog(@"\n %p -> %@ | %p -> %@",&_person, _person, &_personCopy, _personCopy);
// 0x7fff5fbff770 -> name: 小名, age: 26, title: CEO | 0x7fff5fbff768 -> name:小名, age: 26, title: CEO
_personCopy = [_person copy];///想要不崩溃,需遵循NSCoping协议,并实现协议方法 copyWithZone:
_personCopy.name =@"小明";
NSLog(@"\n %p -> %@ | %p -> %@",&_person, _person, &_personCopy, _personCopy);
// 0x7fff5fbff770 -> name: 小名, age: 26, title: CEO | 0x7fff5fbff768 -> name:小明, age: 26, title: CEO
_person.name =@"小张";
_personCopy = [_person mutableCopy];
NSLog(@"\n %p -> %@ | %p -> %@",&_person, _person, &_personCopy, _personCopy);
// 0x7fff5fbff770 -> name: 小张, age: 26, title: CEO | 0x7fff5fbff768 -> name:小张, age: 26, title: CEO
_结语:
copy和 mutablecopy是两个写在 NSObject中的方法,是利用协议代理方法保留一套接口,OC 实现了(字符串,数组,集合,字典,NSData ,NSURL,NSIndeSet )这些基本OC对象数据类型的接口方法,对于其他的自定义OC对象,要使用copy 和mutablecopy方法需要手动添加协议(<NSCopying,NSMutableCopying>),并实现两个协议的required方法(mutableCopyWithZone: | copyWithZone:)。
协议方法中必定需要返回一个 对象类型,具体怎么处理权限上就是任coder的意志决定,然而此处最好准许OC基本对象数据类型的规律。
- copy|mutablecopy 小述
- copy 、mutableCopy
- Copy & MutableCopy
- copy mutableCopy
- copy && mutableCopy
- Copy,mutableCopy和retain的区别的小理解
- mutableCopy与COPY区别
- Copy and MutableCopy
- 对象的copy&mutableCopy
- copy和mutableCopy
- 对象的copy&mutableCopy
- iphone copy 和mutablecopy
- copy、mutableCopy详解
- copy、mutableCopy详解
- copy和mutablecopy浅见
- copy,mutableCopy 理解
- copy和mutablecopy
- MutableCopy 与 Copy
- shell script 编写和执行
- HDU 1043 Eight(经典八数码问题)对比POJ 1077(bfs)
- Codeforces Round #360 (Div. 2) -- E. The Values You Can Make (DP)
- hash_map和map的区别
- php学习路径
- copy|mutablecopy 小述
- Android客户端上传图片到服务器,服务器存储图片。
- yii学习
- hash_map/unordered_map原理和使用整理
- 测试测试
- Git设置全局忽略文件
- collections
- UITableView滚动时NSTimer不执行
- Linux上查找和放置系统文件