zoukankan      html  css  js  c++  java
  • 浅拷贝、深拷贝

    一.不可变拷贝与可变拷贝

    1.系统对象(集合、字符串、二进制数据)的不可变和可变拷贝:

    • copy方法:对对象不可变拷贝,返回1个不可变拷贝。
    • mutableCopy方法:对对象可变拷贝,返回1个可变对象。

    2.自定义类的不可变拷贝和可变拷贝:

    • 对对象copy方法操作需实现协议<NSCopying>的-(id)copyWithZone:方法,不然程序会蹦。
    • 对对象mutableCopy方法操作需实现协议<NSMutableCopying>的-(id)mutableCopyWithZone:方法,不然程序也会蹦。(通常只用不可变拷贝就可以满足需求,可变拷贝不常用)

    3.

    copy方法:

    • 对不可变对象进行不可变拷贝操作,两者内存地址一致,由于copy返回的是不可变副本,系统只生成一份内存资源,此时的copy只是浅复制,和retain作用完全一样。
    • 对可变对象进行不可变拷贝操作,两者内存地址不一致,引用计数始终为1,与原对象的引用计数无关,返回的是一个新对象。

    mutableCopy方法:

    引用计数始终为1,与原对象的引用计数无关,返回一个新对象。(该新对象可变,对源对象不影响)


    二.深拷贝与浅拷贝

    1.

    浅拷贝:拷贝引用对象的指针。(指针的原因,改变其值对原对象有影响)
    深拷贝:拷贝引用对象的内容。(拷贝一份副本,改变其值对原对象不影响)

    2.对象的深、浅拷贝:

    • 浅拷贝:对对象的一层(即不包括对象的属性)拷贝是内容拷贝。即只拷贝了对象,没有拷贝属性(只是引用指针)。
    • 深拷贝:对对象的每一层拷贝都是内容拷贝。即拷贝了对象也拷贝了属性。(通过集合是否copyItems触发<NSCopying>协议的allocWithZone:方法或归档写入缓存区实现)

    Student.h

    #import <Foundation/Foundation.h>
    
    @interface Student : NSObject <NSCopying,NSCoding>
    {
        NSString *_name;
        int _age;
    }
    @property(nonatomic,assign)int age;
    -(void)setName:(NSString *)aName;
    -(NSString *)name;
    @end

    Student.m

    #import "Student.h"
    
    @implementation Student
    @synthesize age = _age;
    -(void)setName:(NSString *)aName
    {
        if (_name != aName)
        {
            [_name release];
            _name = [aName copy];
        }
    }
    
    -(NSString *)name
    {
        return _name;
    }
    //NSCopying Delegate Method
    -(id)copyWithZone:(NSZone *)zone
    {
        Student *stu = [[Student allocWithZone:zone]init];//新创建一个副本对象
        stu.name = self.name;
        stu.age = self.age;
        return [stu autorelease];
    }
    //编码
    -(void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:_name forKey:@"name"];
        [aCoder encodeInteger:_age forKey:@"age"];
    }
    //解码
    -(id)initWithCoder:(NSCoder *)aDecoder
    {
        self = [super init];
        if (self)
        {
            self.name = [aDecoder decodeObjectForKey:@"name"];
            self.age = [aDecoder decodeIntegerForKey:@"age"];
        }
        return self;
    }
    
    -(NSString *)description// 当用%@输出该对象时自动调用
    {
       return [NSString stringWithFormat:@"my name is %@,my age is %d",self.name,self.age ];
    }
    -(void)dealloc
    {
        [_name release];
        [super dealloc];
    }
    @end

    AppDelegate.m

        NSMutableArray *stuArray = [[NSMutableArray alloc]initWithCapacity:10];
        for (int i = 0;i < 10 ;i++)
        {
            Student *stu1 = [[Student alloc]init];
            stu1.name = [NSString stringWithFormat:@"man%d",i];
            stu1.age = i;
            [stuArray addObject:stu1];
            [stu1 release];
        }
        
    // 1.浅拷贝
    // NSMutableArray *arr2 = [[NSMutableArray alloc]initWithArray:stuArray];
    //浅拷贝 // [[arr2 objectAtIndex:0] setName:@"superMan"]; // NSLog(@"%@",arr2); // NSLog(@"%@",stuArray);
    // 深拷贝:通过集合的copyItems触发<NSCopying>协议实现深拷贝 // NSMutableArray *arr3 = [[NSMutableArray alloc]initWithArray:stuArray copyItems:YES];//完全拷贝,实现<NSCopying>协议 // [[arr3 objectAtIndex:0] setName:@"batMan"]; // NSLog(@"%@,arr3 = %p",arr3,arr3); // NSLog(@"%@,stu = %p",stuArray,stuArray); //2.通过归档实现深拷贝(关于路径的部分不用写,NSData作缓冲区) NSData *data = [NSKeyedArchiver archivedDataWithRootObject:stuArray]; NSMutableArray *arr4 = [NSKeyedUnarchiver unarchiveObjectWithData:data]; [[arr4 objectAtIndex:0] setName:@"outeMan"]; NSLog(@"%@",arr4); NSLog(@"%@",stuArray);

     转:http://www.cnblogs.com/eagle927183/p/3462439.html

  • 相关阅读:
    Leetcode:50. Pow(x, n)
    loj 2759「JOI 2014 Final」飞天鼠
    bzoj 3569 DZY Loves Chinese II
    CF407D Largest Submatrix 3
    bzoj 3837 pa2013 Filary
    bzoj 4722 由乃
    CF1105E Helping Hiasat
    loj 6043「雅礼集训 2017 Day7」蛐蛐国的修墙方案
    luogu P2605 [ZJOI2010]基站选址
    luogu P3226 [HNOI2012]集合选数
  • 原文地址:https://www.cnblogs.com/huen/p/3535437.html
Copyright © 2011-2022 走看看