深拷贝:是指对 堆中已存在的内存空间进行的操作,先开辟一块新的空间(即产生新指针)并将 已存在内存空间的 内容 进行复制进去;
浅拷贝:是指 指针指向堆中已经存在的内存空间,将内容进行复制,并不会开辟新的内存空间(即不会产生新指针);
以下[str retain]的打印结果困扰了我许久,没有想明白,其实这个问题真的是很简单---->retainCount=-1是因为str为字符串常量,系统会用UINT_MAX来标记,系统不收回,也不做引用计数。恍然大悟,瞬间懵逼了~~~
- (void)viewDidLoad {
[super viewDidLoad];
/********************测试一********************/
NSMutableArray *ary = [[NSMutableArray array] retain];
NSString *str = [NSString stringWithFormat:@"test"];
NSLog(@"%@ %d",str,[str retainCount]);
[str retain];
[ary addObject:str];
NSLog(@"%@ %d",str,[str retainCount]);
[str retain];
[str release];
[str release];
NSLog(@"%@ %d",str,[str retainCount]);
[ary removeAllObjects];
NSLog(@"%@ %d",str,[str retainCount]);
/********************测试二********************/
NSString *str1 = [NSString stringWithFormat:@"i"];
NSString *str2 = @"1";
[str2 retain];
NSString *str3 = [NSString stringWithFormat:@"imfais"];
NSLog(@"str1 = %d",[str1 retainCount]); //retaincount = 18446744073709551615
NSLog(@"str2 = %d",[str2 retainCount]);
NSLog(@"str3 = %d",[str3 retainCount]); //retaincount = 1
/********************测试三********************/
NSString *strTest = @"hello gays😄😄😄";
NSString *strRetain = [strTest retain];
NSString *strCopy = [strTest copy];
NSMutableString *strMutCopy = [strTest mutableCopy];
NSLog(@"strTest = %p, retainCount = %d", strTest, [strTest retainCount]);
NSLog(@"strRetain = %p, retainCount = %d", strRetain, [strRetain retainCount]);
NSLog(@"strCopy = %p, retainCount = %d", strCopy, [strCopy retainCount]);
NSLog(@"strMutCopy = %p, retainCount = %d", strMutCopy, [strMutCopy retainCount]);
}
此处的retainCount 均用%d进行打印,有的人用%lu会打一出来一个庞大的数字->18446744073709551615,原因是lu是longInteger,实际值是-1.
观察打印信息可以发现,不管是retain还是copy对于NSString来说都是浅拷贝,还是指向的之前的内存区域。
NSString 应用 retain 还是 copy?
1。对NSString应用retain,效率无疑是最好的
2。用copy最安全,因为NSString 为 NSMutableString 的基类,如果将NSMutableString 以retain的形式赋值给NSString后,后续修改NSMutableString会导致NSString内容的变化,这通常不是我们希望的,所以用copy最安全。