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

简介: 深拷贝&浅拷贝 无论使用什么语言编程我们都必须考虑深拷贝和浅拷贝的问题,只是Objective-c提供了一个实现深拷贝的标准机制而已。所谓浅拷贝其实就是指针的赋值,例如: NSString* str1 = @"Hello World!";NSString* str2 = str1; 此时str1和str2同时指向了内存中的同一片区域,无论使用哪个指针对该区域进行了改动,

深拷贝&浅拷贝

无论使用什么语言编程我们都必须考虑深拷贝和浅拷贝的问题,只是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


相关文章
|
JavaScript 前端开发 Java
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
Objective-C协议(protocol)和委托(delegate)的基本概念(★firecat推荐★)
256 0
|
Java 程序员 iOS开发
|
iOS开发 编译器 数据安全/隐私保护
[精通Objective-C]类,接口,协议与扩展
[精通Objective-C]类,接口,协议与扩展 参考书籍:《精通Objective-C》【美】 Keith Lee 目录 精通Objective-C类接口协议与扩展 目录 类 类的接口 类的实现 实例变量 属性 方法 协议 分类 扩展 类 创建一个类名为Atom,继承于NSObject的类。Atom类由两个文件组成,Atom.h和
2072 0
|
机器学习/深度学习 iOS开发 容器