在 iOS 中,最为重要的一点就是内存管理。而在内存管理时,有时会遇到 copy 出来的对象,是否需要释放内存的情况。所以,本文将讲解下 copy
与 mutableCopy
的用法和区别。
环境信息:
Mac OS X 10.9
Xcode 5.1.1
关闭 ARC 模式
以下所有内容都将以NSString
作为例子进行讲解
// 对于不可变字符串,copy 类似与 retain(浅copy)NSString *string1 = [[NSString alloc] initWithFormat:@"字符串1"];NSString *newString1 = [string1 copy];NSLog(@"%ld", [string1 retainCount]); //2
不可变字符串(字典、集等),copy
操作相当于 retain
(指针拷贝)。
这种 copy 方式,不会分配内存,只是让 newString1
持有了 string1
的内存。
// 对于可变字符串,copy 会重新开辟空间(深 copy)NSMutableString *string2 = [[NSMutableString alloc] initWithFormat:@"字符串2"];NSMutableString *newString2 = [string2 copy];NSLog(@"%ld", [string2 retainCount]); //1
可变字符串(字典、集等),copy
操作相当于 alloc
并且赋值(内存拷贝)。这种 copy 方式,会重新分配内存。
所以对 newString2
操作(修改、release
等)并不会影响到 string2
,因为他们没有在操作同一块内存。
因为 copy 出来的都是不可变对象,所以这里的 newString2
,即使是 NSMutableString
类型,但不能调用可变对象的方法,因为 newString2
已经是不可变对象了。
如果强制调用,程序崩溃,并报错:‘Attempt to mutate immutable object with deleteCharactersInRange:…’ 试图修改一个不可变的对象
// 对于不可变和可变对象,都是内容复制(深 copy)NSString *string3 = [[NSString alloc] initWithFormat:@"字符串3"];NSString *newString3 = [string3 mutableCopy];NSLog(@"%ld", [string3 retainCount]); //1
虽然使用了 NSString
去接收了 mutableCopy
出来的 string3
,但是 newString3
依然是一个可变字符串,可以调用可变字符串的方法,但是会报警告,因为子类调用了父类的方法。
NSMutableString *string4 = [[NSMutableString alloc] initWithFormat:@"字符串4"];NSMutableString *newString4 = [string4 mutableCopy];NSLog(@"%ld", [string4 retainCount]); // 1
对于可变字符串,mutableCopy
依然是可变。
联系客服