Objective-c下的深拷贝、浅拷贝以及NSCopying协议

深拷贝&浅拷贝

无论使用什么语言编程我们都必须考虑深拷贝和浅拷贝的问题,只是Objective-c提供了一个实现深拷贝的标准机制而已。所谓浅拷贝其实就是指针的赋值,例如:

NSString* str1 = @"Hello World!";
NSString* str2 = str1;

此时str1和str2同时指向了内存中的同一片区域,无论使用哪个指针对该区域进行了改动,使用另一个指针获取到的内容也会随之变化。这就是所谓的浅拷贝。而所谓的深拷贝是重新申请一块区域,重新建立一个对象,同时将原有对象的内容全部复制过来。例如:

NSString* str1 = @"Hello World!"
NSString* str2 = [str1 copy];

此时,无论操作哪个指针对其内容进行修改,另外一个指针所指示的内容不会受到影响。这里多说一句,调用NSString的copy函数复制出来的对象实际和原有对象指向的是同一片区域。但是如果如果对其指向的内容进行修改的话,因为NSString属于不可改变(immutable)对象,所以系统会重新申请一片空间,写入修改后的内容返回给该指针。而另外一个指向原来区域的指针不受任何影响。如下:

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* str = @"hello world";
        NSString* str1 = [str copy];
        NSLog(@"str:%p, str1:%p", str, str1);
        
        str = @"liyazhou";
        NSLog(@"str:%@, str1:%@", str, str1);
        NSLog(@"str:%p, str1:%p", str, str1);

    }
    return 0;
}

得到的结果是:


NSCopying&NSMutableCopying协议

之所以可以在Objective-c下使用copy和mutablecopy函数进行对象的拷贝是因为Objective-c实现了NSCopying和NSMutableCopying协议,这两个协议规定了对其所属对象进行复制的具体操作:
@protocol NSCopying

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

@end

@protocol NSMutableCopying

- (id)mutableCopyWithZone:(nullable NSZone *)zone;

@end

这两个协议分别声明了一个方法,而具体的复制操作就在这两个方法中实现。例如调用NSString的copy操作实际就是执行了NSString的copyWithZone函数。

对于常用的类型,这两个协议都已经实现,所以用户只需要调用copy和mutableCopy方法即可,但是对于自定义的类,要想使用copy方法就必须自己实现该协议。例如:

#import <Foundation/Foundation.h>

@interface Person : NSObject<NSCopying>
{
}

@property (nonatomic, strong) NSString* name;
@property (nonatomic) int age;

-(instancetype)init;
-(id)copyWithZone:(NSZone *)zone;
@end

#import "Person.h"


@implementation Person

-(instancetype)init
{
    self = [super init];
    if(self)
    {
        _name = @"李牙刷儿";
        _age = 25;
        
    }
    
    return  self;
}


-(id)copyWithZone:(NSZone *)zone
{
    Person *p = [[Person allocWithZone:zone]init];
    p.name = self.name;
    p.age = self.age;
    return p;
}




@end


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值