• 深浅拷贝的应用-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

  • 相关阅读:
    luogu P1840 Color the Axis_NOI导刊2011提高(05)|并查集
    luogu P5414 [YNOI2019]排序 |动态规划
    luogu P4064 [JXOI2017]加法 |二分+堆
    luogu P4065 [JXOI2017]颜色 |随机化+前缀和
    luogu P2135 方块消除 |dp
    luogu P1650 田忌赛马 |贪心
    IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)?
    IM群聊消息的已读回执功能该怎么实现?
    IPv6技术详解:基本概念、应用现状、技术实践(下篇)
    IPv6技术详解:基本概念、应用现状、技术实践(上篇)
  • 原文地址:https://www.cnblogs.com/liuzhi20101016/p/5086482.html
Copyright © 2020-2023  润新知