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

  • 相关阅读:
    点分治练习
    PKU-2723 Get Luffy Out(2-SAT+二分)
    tarjan求割点与割边
    tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows
    数算日子荣耀神
    《JavaScript DOM编程艺术》笔记
    CSS链接的样式a:link,a:visited,a:hover,a:active
    chrome调试技巧--持续更新
    CSS文字大小单位PX、EM的区别
    【转】如何成为一名优秀的web前端工程师(前端攻城师)?
  • 原文地址:https://www.cnblogs.com/huen/p/3535437.html
Copyright © 2011-2022 走看看