NSString与NSMutableString的深浅拷贝

1.NSString

先看NSString的深浅拷贝

NSString * string = @"hello world";
/** 浅拷贝 */
NSString * copyString = [string copy];
/** 深拷贝 */
NSMutableString * mutableCopyString = [string mutableCopy];
NSLog(@"\nstring = %p\ncopyString = %p\nmutableCopyString = %p",string,copyString,mutableCopyString);

输出结果为:

string = 0x104cae7d0
copyString = 0x104cae7d0
mutableCopyString = 0x7fa400f04fd0

由此看出NSString
- 浅拷贝:未产生新对象
- 深拷贝:产生新对象


2.NSSMutableString

再看NSSMutableString的深浅拷贝

NSMutableString * mString = [NSMutableString stringWithString:@"hello world"];
/**  浅拷贝 */
NSString * copyMString = [mString copy];
/**  深拷贝 */
NSMutableString * mutableCopyMString = [mString mutableCopy];
NSLog(@"\nmString = %p\ncopyMString = %p\nmutableCopyMString = %p",mString,copyMString,mutableCopyMString);

输出结果为:

mString = 0x7ffe42467130
copyMString = 0x7ffe42473b90
mutableCopyMString = 0x7ffe42402a50

由此看出NSSMutableString
- 浅拷贝:产生新对象
- 深拷贝:产生新对象


备注

NSString中,stringWithString已被弃用,直接更改为赋值

NSMutableString中,只可用stringWithString或stringWithFormat,而无法直接赋值

在OC中,stringWithFormat会新申请一片空间并初始化字符串,所以每一个用stringWithFormat方法得到的字符串其指针都是不相同的。

而stringWithString是通过浅拷贝的方式得到字符串,浅拷贝只拷贝指针不拷贝对象,因此指针与内容相同。

另外

快速初始化(initWithString)是首先根据一定的方法(此方法和NSSet(集合)中的存放对象的方法一样都是hash算法)在内存中查找是否已经存在了这样的一个对象,若是存在则放回此对象的指针,若不存在,则根据一定的方法找到一片内存空间存放对象,并返回指针。


3.以下原理相同

NSArray;
NSMutableArray;
NS*;
NSMutable*;

即:

源对象类型拷贝方法副本对象类型是否产生了新对象拷贝类型
NSStringcopyNSStringNO浅拷贝(指针拷贝)
mutableCopyNSMutableStringYES深拷贝(内容拷贝)
NSMutableStringcopyNSStringYES深拷贝(内容拷贝)
mutableCopyNSMutableStringYES深拷贝(内容拷贝)
NSArraycopyNSArrayNO浅拷贝(指针拷贝)
mutableCopyNSMutableArrayYES深拷贝(内容拷贝)
NSMutableArraycopyNSArrayYES深拷贝(内容拷贝)
mutableCopyNSMutableArrayYES深拷贝(内容拷贝)
NS*copyNS*NO浅拷贝(指针拷贝)
mutableCopyNSMutable*YES深拷贝(内容拷贝)
NSMutable*copyNS*YES深拷贝(内容拷贝)
mutableCopyNSMutable*YES深拷贝(内容拷贝)

4.copy NSObject

看个例子

YWMPerson * person = [[person alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson * copyPerson = [person copy]; // 这里崩溃

根据崩溃的信息,应实现:

- (id)copyWithZone:(NSZone *)zone;

则:

#import "YWMPerson.h"
@interface YWMPerson()
@end
@implementation YWMPerson
- (id)copyWithZone:(NSZone *)zone
{
    return @"hello world";
}
@end
YWMPerson * person = [[YWMPerson alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson *copyPerson = [person copy];
NSLog(@"copyPerson: %@", copyPerson);

输出结果为:

copyPerson: hello world

可以看出copyWithZone重新分配新的内存空间,则:

- (id)copyWithZone:(NSZone *)zone
{
    YWMPerson * person = [[YWMPerson allocWithZone:zone] init];
    return person;
// 有些人可能下面alloc,重新初始化空间,但这方法已给你分配了zone,自己就无需再次alloc内存空间了
// YWMPerson * person = [[YWMPerson alloc] init];
}
YWMPerson * person = [[YWMPerson alloc] init];
person.age = 20;
person.height = 170.0;
YWMPerson * copyPerson = [person copy];
NSLog(@"person = %p copyPerson = %p", person, copyPerson);
NSLog(@"age = %d height = %f", copyPerson.age, copyPerson.height);

然而结果却是age与height均为0,虽然copy了份新的对象,然而age,height值并未copy,那么:

- (id)copyWithZone:(NSZone *)zone
{
    YWMPerson *person = [[YWMPerson allocWithZone:zone] init];
    person.age = self.age;
    person.height = self.height;
    // 这里self其实就要被copy的那个对象,很显然要自己赋值给新对象,所以这里可以控制copy的属性
    return person;
}

OK,copy成功!

其实还有NSMutableCopying

- (id)mutableCopyWithZone:(NSZone *)zone{
    //原理与-(id)copyWithZone:(NSZone *)zone相同
}

其实没必要有NSMutableCopying,因为YWMPerson不可变,但如果该对象有其他行为,可以借用NSMutableCopying实现


5.copy与strong

最后是copy与strong

@interface YWMPerson : NSObject
@property (nonatomic,copy)NSString * nameCopyString;
@property (nonatomic,copy)NSMutableString * nameCopyMString;
@end
NSMutableString * mmString = [NSMutableString stringWithFormat:@"string"];  

YWMPerson * person    = [[YWMPerson alloc]init];
person.nameCopyString = mmString;
person.nameStrong     = mmString;
[mmString appendString:@"+++string"];

NSLog(@"name = %@",person.nameCopyString);
NSLog(@"name = %@",person.nameStrong);

输出结果是:

name = string
name = string+++string

看了结果你一定秒懂
- copy不能改变person.nameCopyString的值,因为其内部copy新的对象
- strong可以改变person.nameStrong的值,因为其内部没有生成新的对象

property copy 实际上就对nameCopyString干了这个:

- (void)setNameCopyString:(NSString *)nameCopyString
{
    _nameCopyString = [nameCopyString copy];
}

如果你说我想这样用:

@property (nonatomic,copy)NSMutableString * nameCopyMString;

这回崩了,为啥?因为系统还是这么跑的:

- (void)setNameCopyMString:(NSMutableString *)nameCopyMString
{
    _nameCopyMString = [nameCopyMString copy];
}

copy出来的仍然是不可变字符!如果有人用NSMutableString的方法,就会崩溃。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值