• iOS中copy和strong修饰符的区别


    iOS中copy和strong修饰符的区别

    //用copys修饰的生成的都是不可变的对象 ,如果调用可变类型方法的直接报错
    @property(nonatomic,copy)NSString * cpStr;
    @property(nonatomic,strong)NSString *strongStr;

    1.当copy的对象类型为不可变对象如NSString类型时,和Strong修饰作用是一样的

      NSString *str = @"wxwx";
      self.cpStr =  str;
      self.strongStr = str ;
      str = @"haha";
      NSLog(@"str==%p,
     cpstring==%p,
     storngstr==%p",str,_cpStr,_strongStr);
      NSLog(@"str==%@,
     cpstring==%@,
     storngstr==%@",str,_cpStr,_strongStr);

    //打印信息:

    str==0x105086190,

     cpstring==0x105086170,

     storngstr==0x105086170

    ----------

    str==haha,

     cpstring==wxwx,

     storngstr==wxwx

    很明显两者指向的是同一块内存地址,由于指向不可变的对象不用担心对象值改变引起原始值的变化

    2.再来看两者指向可变对象的时候

     NSMutableString *str = [NSMutableString stringWithFormat:@"caca"];
     
        self.cpStr =  str;
        self.strongStr = str ;
       
        [str insertString:@"ha21" atIndex:0];
     
        
        NSLog(@"str==%p,
     cpstring==%p,
     storngstr==%p",str,_cpStr,_strongStr);
        NSLog(@"str==%@,
     cpstring==%@,
     storngstr==%@",str,_cpStr,_strongStr);

    可以看到打印信息为:

    str==0x600002569aa0,

    cpstring==0xf3479ef8a5126e6a,//指向的地址已经改变

     storngstr==0x600002569aa0

    ----------------------

    str==ha21caca,

     cpstring==caca,//copy对象的值还是原始值。

     storngstr==ha21caca

    由于指向可变的对象,用copy修饰的话就算对象的值发生改变也不会影响本身

    3.深拷贝,浅拷贝

    浅拷贝:指向可变对象的时候利用copy,新产生一份内存,但子对象还是指向原先内存。

    深拷贝:子对象也重新生成一份内存。

    如下代码展示了浅拷贝:

          NSMutableArray *arr1 =[ NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"tom"],[NSMutableString stringWithString:@"jack"], nil];
            NSArray*arr2 = [arr1 copy];
            [arr1[0] appendString:@" new value"];
     
            NSLog(@"浅拷贝---arr1==%@,arr2===%@ 
     地址---arr1=%p,arr2=%p",arr1,arr2,arr1,arr2);

    查看log:

    浅拷贝---arr1==(
        "tom new value",
        jack
    ),arr2===(
        "tom new value",
        jack
    ) 
     地址---arr1=0x1020309e0,arr2=0x102030de0

    很明显,arr1,arr2的内存是不一致的,但里面的子对象指向的内存还是同一块.

    深拷贝:实现深拷贝的方法,需要将子对象也都复制一份。比如通过遍历数组中的每个对象并未没个对象创建新的拷贝.

    下面通过归档实现深拷贝:

            NSMutableArray *agearr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"jack"],[NSMutableString stringWithString:@"tom"], nil];
            NSData *data = [NSKeyedArchiver archivedDataWithRootObject:agearr];
            NSMutableArray* agearr2 = [NSKeyedUnarchiver unarchiveObjectWithData:data];
            NSMutableString *obj1 = agearr2[0];
            [obj1 appendString:@"----some value"];
            
            NSMutableArray *tarr = [agearr mutableCopy];
            [[tarr objectAtIndex:0] appendString:@"==lepp"];
            NSLog(@"age1===%@
     age2===%@ tarr==%@",agearr,agearr2,tarr);

    查看Log:

    age1===(
        "jack==lepp",
        tom
    )
     age2===(
        "jack----some value",
        tom
    ) tarr==(
        "jack==lepp",
        tom
    )
    

    总结:

    当属性为不可变时用copy(防止属性值被篡改),指向可变属性时用strong(注:如果还是用copy,由于copy返回的都是不可变的对象,一旦调用不可变对象的方法就会引起崩溃,所以这里也不能用copy)

    对于其他可变非可变类同理(NSArray,NSMutableArray等)

  • 相关阅读:
    tee:结果输出到文件同时也作为往后的输入信息
    hexdump:查看文件头部信息,以十六制形式查看文件
    删除大文件方法
    rename:批量更改文件名
    求从1加到100的结果
    简书里面的面试题
    开源好网站
    ubuntu 14上安装mysql离线包
    单点登录原理与简单实现---转
    Revit API 判断一个构件在某个视图中的可见性
  • 原文地址:https://www.cnblogs.com/cnman/p/10388467.html
Copyright © 2020-2023  润新知