关于retain以及copy特质的理解

对于深拷贝和浅拷贝一直是objc中得一个重点和难点

这里说一些自己的理解

首先讲一下retain,即对receiver的保留,仅仅使其refcount+1

以NSString对象为例 

在讨论引用计数之前必须声明清楚如NSString*str = @“1234”;这类存储在静态存储区的内存没有引用计数这个概念即refcount对其是没有意义的。

如下例子

NSString*str = [NSString stringWithFormat:@"hello"];

此时str 的refCount为1

NSString* retainStr = [str retain];

此时str与retainStr指向同一块内存,并且他们的refcount都为2

这个例子说明retain只是做了指针的拷贝,并无做内容拷贝亦即c/c++里所说的浅拷贝

不过objc中比C++中更安全,原因如下

在C++中如果对str所指向的内存进行release,那块内存就会被销毁,在去使用str或者retainStr都将使程序出现莫名的错误。

在objc中如果对str所指向的内存进行release,那块内存不会被销毁,因为还有retainStr指向了那块内存,这个时候使用str和retainStr都将是安全的。

 

再者讲一下copy,讲到copy还必须要讲到mutableCopy

copy即对receiver的拷贝,但是copy比retain得情况要复杂一些,因为有些时候copy的意义和retain一样,只是使refcount+1,而有时并不会使refcount+1,而是对对象内存块的深拷贝。

举例说明

NSString*str = [NSString stringWithFormat:@"hello"];

此时str 的refCount为1,这个肯定没问题。

NSString *copyStr = [str copy];

在这中情况下str与copyStr指向同一块内存,并且他们的refcount都为2即如上说的和retain的意义一样。并没有为copyStr复制新的内容。

然而

 NSMutableString *str = [[NSMutableString alloc] initWithFormat:@"123"];

 NSString *copyStr = [s copy];

在这种情况下copyStr指向的内存块与str是不同的,copy函数为str那块内存做了拷贝,并且将新内存的地址赋给copyStr,此时str与copyStr的refcount都是1.

出现这种情况的原因,我的理解是因为str指向可变字符串,而copyStr指向的是不可变字符串,这个时候编译器为copyStr分配了一块新的内存。

 

NSString *str = [NSString stringWithFormat:@"hello"];

NSmutable *String*mcopyStr = [str mutableCopy];

 

NSMutableString*str = [[NSMutableString alloc] initWithFormat:@"123"];

NSMutableString *copyStr= [s mutableCopy];

以上两种情况也和上面的现象一样,是深拷贝。

 

结论:1.向NSString对象发送copy消息,这时候copy和retain的意义是一样的

    2.向NSMutableString对象发送copy,此时是深度拷贝

    3.向NSString/NSMutableString对象发送mutableCopy,此时是深度拷贝

总结以上三个结论可以得出以下两个结论

    1.对于不定字符串,系统在进行copy/mutableCopy都会分配新的内存块(即深拷贝)

     2.对于固定字符串发送copy,这个时候是浅拷贝,发送mutableCopy是深拷贝。






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值