1.NSString
先看NSString的深浅拷贝
NSString * string = @"hello world";
/** 浅拷贝 */
NSString * copyString = [string copy];
/** 深拷贝 */
NSMutableString * mutableCopyString = [string mutableCopy];
NSLog(@"\nstring = %p\ncopyString = %p\nmutableCopyString = %p",string,copyString,mutableCopyString);
1
2
3
4
5
6
输出结果为:
string = 0x104cae7d0
copyString = 0x104cae7d0
mutableCopyString = 0x7fa400f04fd0
1
2
3
由此看出NSString中
- 浅拷贝:未产生新对象
- 深拷贝:产生新对象
2.NSSMutableString
再看NSSMutableString的深浅拷贝
NSMutableString * mString = [NSMutableString stringWithString:@"hello world"];
/** 浅拷贝 */
NSString * copyMString = [mString copy];
/** 深拷贝 */
NSMutableString * mutableCopyMString = [mString mutableCopy];
NSLog(@"\nmString = %p\ncopyMString = %p\nmutableCopyMString = %p",mString,copyMString,mutableCopyMString);
1
2
3
4
5
6
输出结果为:
mString = 0x7ffe42467130
copyMString = 0x7ffe42473b90
mutableCopyMString = 0x7ffe42402a50
1
2
3
由此看出NSSMutableString中
- 浅拷贝:产生新对象
- 深拷贝:产生新对象
备注
NSString中,stringWithString已被弃用,直接更改为赋值
NSMutableString中,只可用stringWithString或stringWithFormat,而无法直接赋值
在OC中,stringWithFormat会新申请一片空间并初始化字符串,所以每一个用stringWithFormat方法得到的字符串其指针都是不相同的。
而stringWithString是通过浅拷贝的方式得到字符串,浅拷贝只拷贝指针不拷贝对象,因此指针与内容相同。
另外
快速初始化(initWithString)是首先根据一定的方法(此方法和NSSet(集合)中的存放对象的方法一样都是hash算法)在内存中查找是否已经存在了这样的一个对象,若是存在则放回此对象的指针,若不存在,则根据一定的方法找到一片内存空间存放对象,并返回指针。
3.以下原理相同
NSArray;
NSMutableArray;
NS*;
NSMutable*;
1
2
3
4
即:
源对象类型 拷贝方法 副本对象类型 是否产生了新对象 拷贝类型
NSString copy NSString NO 浅拷贝(指针拷贝)
mutableCopy NSMutableString YES 深拷贝(内容拷贝)
NSMutableString copy NSString YES 深拷贝(内容拷贝)
mutableCopy NSMutableString YES 深拷贝(内容拷贝)
NSArray copy NSArray NO 浅拷贝(指针拷贝)
mutableCopy NSMutableArray YES 深拷贝(内容拷贝)
NSMutableArray copy NSArray YES 深拷贝(内容拷贝)
mutableCopy NSMutableArray YES 深拷贝(内容拷贝)
NS* copy NS* NO 浅拷贝(指针拷贝)
mutableCopy NSMutable* YES 深拷贝(内容拷贝)
NSMutable* copy NS* YES 深拷贝(内容拷贝)
mutableCopy NSMutable* YES 深拷贝(内容拷贝)
4.copy NSObject
看个例子
YWMPerson * person = [[person alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson * copyPerson = [person copy]; // 这里崩溃
1
2
3
4
根据崩溃的信息,应实现:
- (id)copyWithZone:(NSZone *)zone;
1
则:
#import "YWMPerson.h"
@interface YWMPerson()
@end
@implementation YWMPerson
- (id)copyWithZone:(NSZone *)zone
{
return @"hello world";
}
@end
1
2
3
4
5
6
7
8
9
YWMPerson * person = [[YWMPerson alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson *copyPerson = [person copy];
NSLog(@"copyPerson: %@", copyPerson);
1
2
3
4
5
输出结果为:
copyPerson: hello world
1
可以看出copyWithZone重新分配新的内存空间,则:
- (id)copyWithZone:(NSZone *)zone
{
YWMPerson * person = [[YWMPerson allocWithZone:zone] init];
return person;
// 有些人可能下面alloc,重新初始化空间,但这方法已给你分配了zone,自己就无需再次alloc内存空间了
// YWMPerson * person = [[YWMPerson alloc] init];
}
1
2
3
4
5
6
7
YWMPerson * person = [[YWMPerson alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson * copyPerson = [person copy];
NSLog(@"person = %p copyPerson = %p", person, copyPerson);
NSLog(@"age = %d height = %f", copyPerson.age, copyPerson.height);
1
2
3
4
5
6
然而结果却是age与height均为0,虽然copy了份新的对象,然而age,height值并未copy,那么:
- (id)copyWithZone:(NSZone *)zone
{
YWMPerson *person = [[YWMPerson allocWithZone:zone] init];
person.age = self.age;
person.height = self.height;
// 这里self其实就要被copy的那个对象,很显然要自己赋值给新对象,所以这里可以控制copy的属性
return person;
}
1
2
3
4
5
6
7
8
OK,copy成功!
其实还有NSMutableCopying
- (id)mutableCopyWithZone:(NSZone *)zone{
//原理与-(id)copyWithZone:(NSZone *)zone相同
}
1
2
3
其实没必要有NSMutableCopying,因为YWMPerson不可变,但如果该对象有其他行为,可以借用NSMutableCopying实现
5.copy与strong
最后是copy与strong
@interface YWMPerson : NSObject
@property (nonatomic,copy)NSString * nameCopyString;
@property (nonatomic,copy)NSMutableString * nameCopyMString;
@end
1
2
3
4
NSMutableString * mmString = [NSMutableString stringWithFormat:@"string"];
YWMPerson * person = [[YWMPerson alloc]init];
person.nameCopyString = mmString;
person.nameStrong = mmString;
[mmString appendString:@"+++string"];
NSLog(@"name = %@",person.nameCopyString);
NSLog(@"name = %@",person.nameStrong);
1
2
3
4
5
6
7
8
9
输出结果是:
name = string
name = string+++string
1
2
看了结果你一定秒懂
- copy不能改变person.nameCopyString的值,因为其内部copy新的对象
- strong可以改变person.nameStrong的值,因为其内部没有生成新的对象
property copy 实际上就对nameCopyString干了这个:
- (void)setNameCopyString:(NSString *)nameCopyString
{
_nameCopyString = [nameCopyString copy];
}
1
2
3
4
如果你说我想这样用:
@property (nonatomic,copy)NSMutableString * nameCopyMString;
1
这回崩了,为啥?因为系统还是这么跑的:
- (void)setNameCopyMString:(NSMutableString *)nameCopyMString
{
_nameCopyMString = [nameCopyMString copy];
}
1
2
3
4
copy出来的仍然是不可变字符!如果有人用NSMutableString的方法,就会崩溃。
————————————————
版权声明:本文为CSDN博主「夜O无眠」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_25921367/article/details/48318587