深浅拷贝的应用-copy、mutableCopy

ViewController.h

#import <UIKit/UIKit.h>

 

@interface ViewController : UIViewController

 

//如果想让list成为一个可变的数组,需要把copy变成retain,因为copy之后的对象永远都只是一个不可变的对象

@property (nonatomic,copy)NSMutableArray *list;

 

@end

 

 

ViewController.m

/*

 拷贝:复制一个对象->变成另外一个对象

 

 深拷贝:复制对象并且复制对象里面的内容,完全拷贝

 浅拷贝:指针拷贝,只拷贝对象本身,不拷贝里面的内容

 

 看是不是深拷贝,主要看是不是拷贝了对象里面的内容

 

 系统自带的拷贝都是浅拷贝,eg:copymutableCopy

 

 实现深拷贝的方式:

 1、自定义拷贝(要看具体拷贝内容的实现)

 2、系统提供给了深拷贝的方法

 1)数组:- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag

 2)字典:- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary copyItems:(BOOL)flag

 

 

 自定义拷贝:

 1copyWithZone:

 2mutableCopyWithZone:

 

 并不是所有对象都可以拷贝 ->只有遵守了拷贝协议的对象才可拷贝

 

 mutableCopy:?深浅拷贝

 指针拷贝 ->浅拷贝

 对象拷贝 ->深拷贝

 mutableCopy ->深拷贝

 在使用mutableCopy 拷贝后两个对象的内存地址是不一样的

 

 拷贝对象的内容 的内存地址是否发生改变 ->mutableCopy属于浅拷贝

 

 */

#import "ViewController.h"

#import "UserInfoModel.h"

 

@interface ViewController ()

 

@end

 

@implementation ViewController

 

- (void)viewDidLoad {

    [super viewDidLoad];

    

    UserInfoModel *red = [[UserInfoModel alloc]init];

    

    UserInfoModel *yellow = [[UserInfoModel alloc]init];

    UserInfoModel *blue = [[UserInfoModel alloc]init];

    

    NSArray *colorList = @[red,yellow,blue];

    NSLog(@"拷贝前%p",colorList[0]);

    

    //copyItems 如果设置的是YES就是深拷贝

//    NSArray *newList = [[NSArray alloc]initWithArray:colorList copyItems:YES];

    NSArray *newList = [colorList mutableCopy];

    NSLog(@"拷贝后%p",newList[0]);

//    [red copy];

    

    

    red.list = [NSMutableArray arrayWithObjects:@"1", nil];

    [red.list  addObject:@"2"];

    

    UserInfoModel *new = [red mutableCopy];

    [new.list addObject:@"3"];

    /*

     copy :拷贝之后的对象是不可变的对象

     mutableCopy:拷贝之后的对象是可变的对象,但是必须用对应的类型去接收

     

     */

    //NSArray *list = @[];

//    NSMutableArray *newList = [list mutableCopy];

    

    //要想把拷贝之后的对象变成可变的必须用可变的数据类型去接收

//    NSArray *newList = [list mutableCopy];

//    [newList addObject:@"1"];

    /*

     **************************************************************

     *

     *不可变对象 copy ->不可变对象 ->不管用可变或者不可变类型接收 都是不可变

     *可变对象 copy ->不可变对象 ->不管用可变或者不可变类型接收 都是不可变

     *

     *不可变对象 mutableCopy -> 可变对象 ->不可变对象接收 -> 不可变对象

     *不可变对象 mutableCopy -> 可变对象 ->可变对象接收 -> 可变对象

     *可变对象   mutableCopy -> 可变对象 ->不可变对象接收 -> 不可变对象

     *可变对象 mutableCopy -> 可变对象 ->可变对象接收 -> 可变对象

     *

     **************************************************************

     *总结:(1)只要使用copy就是不可变对象

            @property (nonatomic,copy)NSMutableArray *list; 

              在声明可变数组的属性的时候,只要使用copy这个关键字就会变成不可变的数组

              原因:在setter方法的实现中全部使用了copy

           2)使用mutableCopy必须使用可变类型接收,才是可变对象

     

     自定义拷贝:

      并不是所有类型 都可以拷贝 ->如果想让不可以拷贝的类型实现拷贝 ->自定义拷贝

      可以拷贝的数据类型:nsstring nsarray nsdictionary

     自定义拷贝的步骤:

      1、导入拷贝协议

      2、实现协议的方法

      1copyWithZone:

      2mutableCopyWithZone:

     */

    

    //不管用什么数据类型接收copy之后的内容,都是一个不可变的对象

//    NSArray *list1 = @[];

//    NSMutableArray *new1 = [list1 copy];

//    [new1 addObject:@"1"];                会奔溃  

    

}

 

 

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

@end

UserInfoModel.h

#import <Foundation/Foundation.h>

//1、遵守拷贝协议

@interface UserInfoModel : NSObject<NSCopying,NSMutableCopying>

 

@property(nonatomic,retain)NSMutableArray *list;

 

@property(nonatomic,retain)NSMutableDictionary *info;

 

 @end

UserInfoModel.m

#import "UserInfoModel.h"

 

@implementation UserInfoModel

 

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

{

    

    //allocWithZone: 是在执行cop的时候分配内存

    UserInfoModel *new = [[UserInfoModel allocWithZone:zone]init];

    

    //new是拷贝之后的新的对象

    new.list = [self.list copy];

    new.info = [self.info copy];

    

    return new;

 

}

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

{

    

    UserInfoModel *new = [[UserInfoModel allocWithZone:zone]init];

    

    new.list = [self.list mutableCopy];

    new.info = [self.info mutableCopy];

    

    return new;

}

 

 

@end

原文地址:https://www.cnblogs.com/liuzhi20101016/p/5086482.html