一直以为copy就是深拷贝,会产生一个新的对象,指针和内容都是新的,retain只是引用计数+1。
今天测试代码的时候发现一个问题,再经仔细一测,才发现不是这么回事.
int main(int argc, char *argv[])
{
NSString *str = @"google";
NSString *strRetain = [str retain];
NSString *strCopy = [str copy];
NSMutableString *strMutCopy = [str mutableCopy];
NSLog(@"str = %p, retainCount = %d", str, [str 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]);
}
output:
观察打印信息可以发现,不管是retain还是copy对于NSString来说都是浅拷贝,还是指向的之前的内存区域。retainCount=-1是因为str为字符串常量,系统会用UINT_MAX来标记,系统不收回,也不做引用计数。
NSString 应用 retain 还是 copy?
1。对NSString应用retain,效率无疑是最好的
2。用copy最安全,因为NSString 为 NSMutableString 的基类,如果将NSMutableString 以retain的形式赋值给NSString后,后续修改NSMutableString会导致NSString内容的变化,这通常不是我们希望的,所以用copy最安全。
参考文档 NSCopying Protocol Reference
Your options for implementing this protocol are as follows:
- Implement NSCopying using alloc and init... in classes that don’t inherit copyWithZone:.
- Implement NSCopying by invoking the superclass’s copyWithZone: when NSCopying behavior is inherited. If the superclass implementation might use the NSCopyObject function, make explicit assignments to pointer instance variables for retained objects.
- Implement NSCopying by retaining the original instead of creating a new copy when the class and its contents are immutable.