iOS的各种拷贝

熟悉了内存的分配方式的一些基础知识后,接下来就是关于copy和mutableCopy了。
对一个不可变数组进行copy,返回的实际是自身,对一个不可变数组进行mutableCopy,会产生一个新的可变数组。
在OC中,所有的对象的copy和mutableCopy,都是分别遵循了NSCopy和NSMutableCopy协议,需要对应实现的方法就是 - (id)copyWithZone:(NSZone *)zone- (id)mutableCopyWithZone:(NSZone *)zone

  1. 系统容器类 如:NSString、NSArray、NSDictionary等,他们已经遵循了上面的两个协议,并且实现了上面两个方法
		NSString *Str = @"123";
       	NSString *newStr = [Str copy];
        /*NSString *st = [Str mutableCopy];*/
        id st = [Str mutableCopy];

对于它们来说,规则很简单
obj2 = [obj1 copy]返回的必然是一个不可变对象
obj2 = [obj1 mutableCopy]返回的必然是一个可变对象,无论obj1是可变对象还是不可变对象。即使obj1也是一个可变对象,它们仍指向不同地址,是两个对象。
一个简单的分析

// 关于深浅拷贝的探究
- (void)testCopy {
    // 对不可变string 拷贝
    NSString *baseString = @"a new string";
    NSString *copyStr = [baseString copy];
    NSMutableString *mutableCopyString = [baseString mutableCopy];
    
    NSLog(@"------%p \n %p \n %p",baseString,copyStr, mutableCopyString);
    /**
     0x1057b10b8
     0x1057b10b8
     0x600000b86d90
     */
    
    // 对可变对象拷贝
    NSMutableString *mutableBaseString = [[NSMutableString alloc] initWithString:@"test string"];
    NSString *sCopyString = [mutableCopyString copy];
    NSMutableString *sMutableCopyString = [mutableCopyString mutableCopy];
    NSLog(@"------%p \n %p \n %p",mutableBaseString,sCopyString, sMutableCopyString);
    /**
     0x6000007a8c90
     0x6000009e3be0
     0x6000007a8ba0
     */
}

**
不可变对象的copy方法进行了浅拷贝
不可变对象的mutableCopy方法进行了深拷贝
可变对象的copy方法进行了深拷贝
可变对象的mutableCopy方法进行了深拷贝。
**

  1. 自定义类
    因为是自定义类 copyWithZone:和mutableCopyWithZone:完全由自己实现,所有代码的实现不同也就决定了返回对象是什么

The returned object is implicitly retained by the sender, which is responsible for releasing it. The copy returned is mutable whether the original is mutable or not.

分析 实现源码

NSString copy
-(id)copyWithZone:(NSZone )zone {
if (NSStringClass == Nil)
NSStringClass = [NSString class];
return RETAIN(self);
}
-(id)mutableCopyWithZone:(NSZone
)zone {
return [[NSMutableString allocWithZone:zone] initWithString:self];
}

NSMutableString copy
-(id)copy {
return [[NSString alloc] initWithString:self];
}
-(id)copyWithZone:(NSZone*)zone {
return [[NSString allocWithZone:zone] initWithString:self];
}

NSMutableString 没有实现mutableCopyWithZone: 但是他继承NSObject 所以会调用父类的mutableCopyWithZone:方法

NSObject copy
-(id)copy {
return [(id)self copyWithZone:nil];
}
-(id)mutableCopy {
return [(id)self mutableCopyWithZone:nil];
}

NSArray,NSDictionary,NSSet 这些容器都类似,就不一一叨叨了。

Question:
NSString类型的成员变量的修饰属性用copy还是strong呢?
成员变量用copy修饰和用strong修饰的区别:如果使用了copy修饰符,那么在给成员变量赋值的时候就会对被赋值的对象进行copy操作,然后再赋值给成员变量。如果使用的是strong修饰符,则不会执行copy操作,直接将被赋值的变量赋值给成员变量
如果成员变量一直保持的是NSString类型,copy和strong肯定是没有区别的
但是,由于OC的特性,虽然成员变量在编译器编译的时候是保持着NSString类型,但是如果
执行下面的操作,当mutableString的值发生了改变后,baseString的值也随之发生改变

NSMutableString *mutableString = [[NSMutableString alloc] initWithString:@“Steven”];
self.baseString = mutableString;
[mutableString appendString:@" Kyle"];

所有为了避免这种不确定性因素,最好还是使用copy修饰

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值