iOS开发基础篇

iOS对象的拷贝

2017-02-15  本文已影响16人  Cheriez

一 :拷贝的相关概念

copy语法的目的:改变副本的时候,不会影响到源对象;

深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

二:拷贝的实现

实现copy,必须实现<NSCopying>协议 ,即 copyWithZone方法,返回一个不可变对象。

实现mutableCopy,必须实现<NSMutableCoping>协议,即 mutableCopyWithZone方法 ,返回一个可变对象。

对于数组,字典,字符串 等都已经实现了<NSCopying>的协议。

三:数组、字典、字符串等拷贝原则

1.对于系统的非容器类的拷贝

对于不可变对象 ,copy实际是浅拷贝,mutableCopy是深拷贝。

对于可变对象 ,copy、mutableCopy都是深拷贝

2.对于系统的容器类的拷贝

以上原则同样是适用的,但是容器类的对象都是指针拷贝。

如果想要元素对象也是对象复制,就需要实现深拷贝。

参考苹果官方文档

四:自定义对象的拷贝

Person.h

#import@interface Person : NSObject

@property (nonatomic,retain) NSMutableArray *apples;

@property (nonatomic,assign) int                         age;

@end

Person.m

#import "Person.h"

@implementation Person

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

        Person *p = [[self class] allocWithZone:zone];

        p.apples = [_apples mutableCopy];

        p.age = _age;

        return p;

}

@end

测试

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

p.apples = [NSMutableArray arrayWithObjects:@"iphone",@"ipad", nil nil];

p.age = 20;

Person *p1 = [p copy];

if(p != p1){

        NSLog(@"p1.age=%d",p1.age);

        NSLog(@"p1.apples=%@",p1.apples);

}

五:理解下property里的copy、strong区别

copy

#import@interface Person : NSObject

@property (nonatomic,copy  ) NSString      *name;

@end

NSMutableString *string = [[NSMutableString alloc] initWithString:@"1111"];

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

person.name = string;

[string appendString:@"1233"];

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

- (void)setName:(NSString *)name

{

        _name = [name copy];

}

假设name为NSMutableString,会发生什么事?

@property (nonatomic, copy) NSMutableString *name;

实际上内部还是:

- (void)setName:(NSMutableString *)name

{

        _name = [name copy];

}

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

[person.name appendString:@"1233"];

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);

上一篇下一篇

猜你喜欢

热点阅读