ios拷贝小议

本文详细解析了Objective-C中的copy、mutableCopy与retain的区别及使用场景,包括不可变对象与可变对象的内存管理,并通过实例展示了它们在实际编程中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

之前对于copy属性了解不深,看到这篇文章讲解很到位,转载推荐。


作者:helmsman_mac | 发布时间:12:29 下午

1.copy vs mutableCopy
copy,对于不可变的对象,简单的指向其内存.对于可变对象,复制内存内容到新的内存中并把新的内存值赋值给左值.
mutableCopy,始终复制到新的内存中,以一个可变的类型赋值给左值.
2.copy vc retainretain,引用计数+1,内存地址赋值给左值.copy,对于不可变对象的,相当于retain;对于可变对象,则是深拷贝赋值.举例:

NSString* a = [NSString stringWithFormat:@"%@",@"this is a"];
 
    NSString* b = [a copy];
 
    NSString* bb = [a retain];
 
    NSString* cc = [a mutableCopy];//实际上cc应该是NSMutableString类型
 
    NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);
 
//输出3,3,3,1
 
NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];
 
    NSString* b = [a copy];//不可变的b
 
    NSString* bb = [a retain];//实际类型是NSMutableString的bb
 
    NSString* cc = [a mutableCopy];//同上
 
    NSLog(@"%d,%d,%d,%d",[a retainCount],[b retainCount],[bb retainCount],[cc retainCount]);
 
//输出2,1,2,1

3.一些问题通过上面2点,思考下面的问题我们通常如果这样定义一个变量 @property(nonatomic,copy) NSMutableString* mString;

然后这样使用

@synthesize mString;
 
NSMutableString* a = [NSMutableString stringWithFormat:@"%@",@"this is a"];
 
self.mString = a;
 
[mString insertString:@"m-" atIndex:0];

能通过么?当然不能,赋值后的mString是NSString类型的,不可变.如果需要可以改变就需要自己定义属性函数.

-(void)setMString:(NSMutableString *)m
 
{
 
    mString = [m mutableCopy];
 
}
 
-(NSMutableString *)mString
 
{
 
    return mString;
 
}

(当然,NSMutableString不是线程安全的,一般都建议私有之:@private;或者一定要用的话以NSString作为对外接口类型)
4.NSCopying NSMutableCopying NSCopyObjective()
NSCopying就是复制一个对象
NSMutableCopying就是深拷贝一个对象,让两个对象的改变互不影响
(其实上面着两个完全看你怎么写啦)
NSCopyObject(self,0,zone)就是简单的赋值=
(在涉及到ns对象的时候,NSCopyObject不建议使用)
注意看下面一个例子:

@interface ClassB : NSObject <NSCopying>{
    NSString* stringB;
}
 
@property(nonatomic,copy) NSString* stringB;
 
@end
 
-(id)copyWithZone:(NSZone *)zone
 
{
 
    ClassB *b = NSCopyObject(self, 0, zone);
 
// 使用NSCopyObject时的正确赋值方法,因为没有涉及到原来的内存指针什么事
 
    b->stringB = @"what";
 
// 看看被注释的这个错误方法,由于setter方法的特性,原来的stringB指向的内存的retainCount减一
 
// 而由于NSCopyObject的特性,两者又是指向同一个地址的,所以,原类中stirngB指向的地址已经释放了,之后你dealloc中在释放一次?!.就出错啦
 
//    b.stringB = @"what";
 
    return b;
 
}

无觅相关文章插件,快速提升流量

   转载本站文章请注明出处,转载自:舵手网络--http://www.helmsmansoft.com

   本文链接地址: http://www.helmsmansoft.com/index.php/archives/957

   网海遨游找舵手-技术分享,分享经验,分享快乐-[舵手网络



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值