ios copy相关

ios 深浅拷贝的区别

深拷贝:对象拷贝,会产生新对象,引用计数+1;
浅拷贝:指针拷贝,不会产生新对象,引用计数不变;
深浅拷贝的判断依据:A:查看原来变量和拷贝的变量是否是同一个内存地址;B:或者去改变原来变量和拷贝变量其中一个的相关属性值,去看另外一个变量是否会发生变化;

系统原生对象深浅拷贝的区别

1.NSObject 类提供了copy 和mutableCopy方法,通过这两个方法即可拷贝已有对象的副本;
2.系统原生对象:NSString 和NSMutableString、NSArray 和NSMutableArray、NSDictionary和NDMutableDictionary、NSSet和NSMutableSet等,这些对象都遵循了NSCopying,NSMutableCopying协议NSValue、NSNumber只遵循了NSCopying协议。
3.不可变类型通过copy之后,是浅拷贝,mutableCopy之后是深拷贝;可变类型通过copy和mutableCopy之后都是深拷贝;无论是可变类型还是不可变类型,copy 之后都是不可变类型;

自定义对象拷贝

实际开发中我们也常会用到自定义对象拷贝;
对自定义对象进行copy,对象必须实现copy 的相关协议(NSCopying或者NSMutableCopy),否则会报错;例如:-[Person copyWithZone:]: unrecognized selector sent to instance 0x1c4030900

copy事例:
自定义Person类具有name,age,dog属性


@interface Dog : NSObject
@property(nonatomic,copy)NSString *color;
@end


@interface Person : NSObject
@property(nonatomic,copy)NSString *name;
@property(nonatomic,copy)NSString *age;

@property(nonatomic,strong)Dog *dog;

@end

以上代码Person类并不具备copy 功能,当我们对其使用copy方法就会报错:[Person copyWithZone:]: unrecognized selector sent to instance 0x1c4030900;

要让Person具备copy 功能必须让其遵循NSCopying协议,并且实现该协议;

#import "Person.h"

@implementation Person

- (nonnull id)copyWithZone:(nullable NSZone *)zone {
   
    Person *per = [[[self class] allocWithZone:zone]init];
    per.name = self.name;
    per.age = self.age;
    
    //dog 是一个对象,用这种方法并不是完全的深拷贝,
    //拷贝之后的对象和原对象共同拥有一个dog
    //要达到完全深拷贝,让Dog 也实现copy协议并且代码改为 per.dog = [self.dog copy];
//    per.dog = self.dog;
    
    Dog *dog = [[Dog alloc]init];
    dog.color = self.dog.color;
    self.dog = dog;
   
    return per;
}
@end

综上述:要让一个自定对象具有拷贝功能,那么该对象必须实现NSCopying协议或者NSMutableCopying协议;当对象调用copy或者mutableCopy方法的时候,系统会触发协议中的方法

@protocol NSCopying

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

@end

@protocol NSMutableCopying

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

@end

验证copy 的常用方法

将原对象地址和copy之后的对象地址作比较

   // 内存地址一样为浅拷贝,内存地址不一样的为深拷贝
 //原对象
    NSArray *arr = [NSArray array];
    NSMutableArray *mut = [NSMutableArray array];
    
 //拷贝案例
    NSArray *copyArr = arr.copy; //不可变数组的copy
    NSLog(@"arr:%p--copyArr:%p",arr,copyArr); //查看内存地址是否一样
    
    NSArray *mutcopyArr = arr.mutableCopy;//不可变数组的mutableCopy
    NSLog(@"arr:%p--mutcopyArr:%p",arr,mutcopyArr); //查看内存地址是否一样
    
   
    NSMutableArray *copyMut = mut.copy; //可变数组的copy
    NSLog(@"mut:%p--copyMut:%p",mut,copyMut);//查看内存地址是否一样
    
    NSMutableArray *mutableCopyMut = mut.mutableCopy; //可变数组的mutableCopy
    NSLog(@"mut:%p--mutableCopyMut:%p",mut,mutableCopyMut);//查看内存地址是否一样
    

Demo

你可能感兴趣的:(ios copy相关)