zoukankan      html  css  js  c++  java
  • ios深拷贝,浅拷贝,拷贝自定义对象的简单介绍(转)

    copy语法的目的:改变副本的时候,不会影响到源对象; 

    深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

    浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

    拷贝有下面两个方法实现拷贝:

    - (id)copy;  
    - (id)mutableCopy;  

    要实现copy,必须实现<NSCopying>协议
    数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例,其他的同理:

    1.不可变字符串调用copy实现拷(浅拷贝)

    NSString *string = [[NSString alloc] initWithFormat:@"abcde"];  
    // copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身  
    // 源对象计数器会+1  
    // 在浅拷贝情况下,copy其实就相当于retain  
    NSString *str = [string copy];  

    2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)

    NSString *string = [[NSString alloc] initWithFormat:@"abcd"];  
    // 产生了一个新的对象,计数器为1。源对象的计数器不变。  
    NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1  
     // str和string不是相同对象  
     // NSLog(@"%i", str == string);//0  
     [str appendString:@" abcd"];//修改str不影响string  
     NSLog(@"string:%@", string);  
     NSLog(@"str:%@", str);  

    3.可变字符串调用copy实现拷贝(深拷贝)

    NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];  
     // 会产生一个新对象,str计数器为1  
     NSString *str = [string copy];  

    4.可变字符串的MutableCopy(深拷贝)

    NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];  
    // 会产生一个新对象,str计数器为1  
    NSMutableString *str = [string mutableCopy];  
    [str appendString:@"1234"];//修改新对象不影响原对象  
    NSLog(@"str:%@", str);  
    NSLog(@"string:%@", string);  

    5.拷贝自定义对象,下面以Student对象为例

    a.Student要实现copy,必须实现<NSCopying>协议

    b.实现<NSCopying>协议的方法:

    - (id)copyWithZone:(NSZone *)zone

    Student.h文件

    @interface Student : NSObject <NSCopying>  
      
    // copy代表set方法会release旧对象、copy新对象  
    // 修改外面的变量,并不会影响到内部的成员变量  
    // 建议:NSString一般用copy策略,其他对象一般用retain  
    @property (nonatomic, copy) NSString *name;  
      
    + (id)studentWithName:(NSString *)name;  
      
    @end

    Student.m文件

    #import "Student.h"  
      
    @implementation Student  
      
    + (id)studentWithName:(NSString *)name {  
        // 这里最好写[self class]  
        Student *stu = [[[[self class] alloc] init] autorelease];  
        stu.name = name;  
          
        return stu;  
    }  
      
    - (void)dealloc {  
        [_name release];  
          
        [super dealloc];  
    }  
      
    #pragma mark description方法内部不能打印self,不然会造成死循环  
    - (NSString *)description {  
        return [NSString stringWithFormat:@"[name=%@]", _name];  
    }  
      
    #pragma mark copying协议的方法  
    // 这里创建的副本对象不要求释放  
    - (id)copyWithZone:(NSZone *)zone {  
        Student *copy = [[[self class] allocWithZone:zone] init];  
          
        // 拷贝名字给副本对象  
        copy.name = self.name;  
          
        return copy;  
    }  
      
    @end  

    拷贝Student

    Student *stu1 = [Student studentWithName:@"stu1"];  
      
    Student *stu2 = [stu1 copy];  
    stu2.name = @"stu2";  
      
    NSLog(@"stu1:%@", stu1);  
    NSLog(@"stu2:%@", stu2);  
      
    [stu2 release];  

    来源:http://blog.csdn.net/daiyelang/article/details/18730303

  • 相关阅读:
    68
    56
    Django manager 命令笔记
    Django 执行 manage 命令方式
    Django 连接 Mysql (8.0.16) 失败
    Python django 安装 mysqlclient 失败
    H.264 SODB RBSP EBSP的区别
    FFmpeg—— Bitstream Filters 作用
    MySQL 远程连接问题 (Windows Server)
    MySQL 笔记
  • 原文地址:https://www.cnblogs.com/JayK/p/4482716.html
Copyright © 2011-2022 走看看