iOS深拷贝与浅拷贝的理解

浅拷贝:拷贝对象本身,返回一个对象指针,指向相同的内存地址。

深拷贝:拷贝内容本身,返回一个对象指针,指向不同的内存地址。

obj2 = [obj1 copy]返回的一个不可变对象,无论obj1是可变对象还是不可变对象。如果obj1是一个不可变对象,那么它们指向同一个对象。obj2 = [obj1 mutableCopy]返回的是一个可变对象,无论obj1是可变对象还是不可变对象。即使obj1也是一个可变对象,它们仍指向不同地址,是两个对象。

源对象类型

拷贝方法

对象类型

是否产生新对象

拷贝类型

NSMutableString

copy

NSString

YES

深拷贝(内容拷贝)

mutableCopy

NSMutableString

YES

深拷贝(内容拷贝)

 

 

 

 

 

NSString

copy

NSString

NO

浅拷贝(指针拷贝)

mutableCopy

NSMutableString

YES

深拷贝(内容拷贝)

 

 

 

 

 

NSArray

copy

NSArray

NO

浅拷贝(指针拷贝)

mutableCopy

 

YES

深拷贝(内容拷贝)

注意:其他对象NSArray、NSMutableArray 、NSDictionary、NSMutableDictionary一样适用

HSPerson *p = [[HSPerson alloc] init];

p.age = 20;

p.height = 170.0;

HSPerson *copyP = [p copy]; # 这里崩溃

看崩溃信息HSPerson应该先实现:

- (id)copyWithZone:(NSZone *)zone;//NSCopying协议方法

测试:

#import "HSPerson.h"

@interface HSPerson()<NSCopying>

@end

@implementation HSPerson

- (id)copyWithZone:(NSZone *)zone

{

    return @"测试copyWithZone";

}

@end

HSPerson *p = [[HSPerson alloc] init];

p.age = 20;

p.height = 170.0;

HSPerson *copyP = [p copy];

NSLog(@"copyP: %@", copyP);

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

- (id)copyWithZone:(NSZone *)zone

{

    HSPerson *person = [[HSPerson allocWithZone:zone] init];

    return person;

// 有些人可能下面alloc,重新初始化空间,但这方法已给你分配了zone,自己就无需再次alloc内存空间了

//    HSPerson *person = [[HSPerson alloc] init];

}

HSPerson *p = [[HSPerson alloc] init];

p.age = 20;

p.height = 170.0;

HSPerson *copyP = [p copy];

NSLog(@"p = %p copyP = %p", p, copyP);

NSLog(@"age = %d height = %f", copyP.age, copyP.height);

虽然copy了份新的对象,然而age,height值并未copy,那么:

- (id)copyWithZone:(NSZone *)zone

{

    HSPerson *person = [[HSPerson allocWithZone:zone] init];

    person.age = self.age;

    person.height = self.height;

    // 这里self其实就要被copy的那个对象,很显然要自己赋值给新对象,所以这里可以控制copy的属性

    return person;

}

- (id)mutableCopyWithZone:(NSZone *)zone

{

    HSPerson *person = [[HSPerson allocWithZone:zone] init];

    person.age = self.age;

    person.height = self.height;

    return person;

}

property里的copy、strong区别

copy

#import <Foundation/Foundation.h>

@interface HSPerson : NSObject

@property (nonatomic, copy) NSString *name;

@end

NSMutableString *string = [NSMutableString stringWithFormat:@“测试"];

HSPerson *person = [[HSPerson alloc] init];

person.name = string;

// 不能改变person.name的值,因为其内部copy新的对象

[string appendString:@" hans"];

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

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

- (void)setName:(NSString *)name

{

    _name = [name copy];

}

@property (nonatomic, copy) NSMutableString *name;

对应:

- (void)setName:(NSMutableString *)name

{

    _name = [name copy];

}

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

strong

@property (nonatomic, strong) NSString *name;

NSMutableString *string = [NSMutableString stringWithFormat:@"测试"];

HSPerson *person = [[HSPerson alloc] init];

person.name = string;

// 可以改变person.name的值,因为其内部没有生成新的对象

[string appendString:@" hans"];

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

总结:用copy与strong取决于需求,如果不希望被外界更改用copy,反之用strong

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值