深复制和浅复制



OC 设计copy语法的目的就是以源对象为基础复制生成一个新的对象, 对新对象的操作不会影响到源对象

对象可以使用copy或mutableCopy方法来创建副本

copy 

需要先实现NSCopping协议, 创建的是不可变副本, 如 NSArray, NSDictionary, NSString...

mutableCopy

需要先实现NSMutableCopping协议, 创建的是可变副本, 如NSMutableString, NSMutableArray, NSMutableDictionary...

深复制

复制对象的一个副本, 源对象引用计数不变, 副本引用计数为1. 源对象和副本对象指向的是两两个不同的对象

浅复制

指针的复制, 源对象引用计数加1, 相当于进行了一次retain操作. 并没有生成新对象


只有不可变对象创建不可变复本才是浅复制,其它都是深复制


//
//  Student.h
//  深复制和浅复制
//
//  Created by LiuWei on 15/4/19.
//  Copyright (c) 2015年 LiuWei. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Student : NSObject

// copy release旧对象, copy新对象
// 自动生成带copy的set方法, 进行深浅复制
@property (nonatomic, copy)NSString* name;
@property (nonatomic, copy)NSMutableString *phoneNumber;

@end

//
//  Student.m
//  深复制和浅复制
//
//  Created by LiuWei on 15/4/19.
//  Copyright (c) 2015年 LiuWei. All rights reserved.
//

#import "Student.h"

@implementation Student

- (void)dealloc
{
    [_phoneNumber release];
    [_name release];
    [super dealloc];
}
@end

//
//  main.m
//  深复制和浅复制
//
//  Created by LiuWei on 15/4/19.
//  Copyright (c) 2015年 LiuWei. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "Student.h"

// NSString的Copy
void copyString();

int main()
{

    // copyString();
        
    NSMutableString *strName = [@"LuCy" mutableCopy];
    NSMutableString *strNumber = [@"13100001111" mutableCopy];
    Student *stu = [[Student alloc]init];
    
    stu.name = strName;
    stu.phoneNumber = strNumber;
    NSLog(@"%@ --- %@", stu.name, stu.phoneNumber);
    //  LuCy --- 13100001111
    
    [strName appendString:@"Fa"];
    NSRange range = [strNumber rangeOfString:@"1111"];
    [strNumber replaceCharactersInRange:range withString:@"2222"];
    
    NSLog(@"%@ --- %@", stu.name, stu.phoneNumber);
    // LuCy --- 13100001111
    NSLog(@"%@ --- %@", strName, strNumber);
    // LuCyFa --- 13100002222
    // 深复制的好处, 对源对象的修改并不会影响到副本对象.
    
        
    [stu release];

    return 0;
}

#pragma NSString的Copy
void copyString()
{
    NSString *str = [[NSString alloc]initWithFormat:@"name is %@, age is %i", @"lili", 28];
    NSLog(@"str = %p, %@, count = %ld", str, str, [str retainCount]);
    // str = 0x100203ea0, name is lili, age is 28, count = 1
    
    // 深复制
    NSMutableString *muStr = [str mutableCopy];
    NSLog(@"muStr = %p, %@, count = %ld", muStr, muStr, [muStr retainCount]);
    // muStr = 0x100103920, name is lili, age is 28, count = 1
    // 两个对象的地址不同, 可以看出是两个完全不同的对象, 源对象引用计数不变, mustr引用计数为1, 是深复制
    
    // 浅复制
    // 由于源对象本身不可变, 为了提高性能, 所以copy返回源对象本身地址
    NSString *str2 = [str copy];
    NSLog(@"str = %p, %@, count = %ld", str, str, [str retainCount]);
    // str = 0x100203ea0, name is lili, age is 28, count = 2
    NSLog(@"str2 = %p, %@, count = %ld", str2, str2, [str2 retainCount]);
    // str2 = 0x100203ea0, name is lili, age is 28, count = 2
    // str2 和 str 所指向的对象相同, str引用计数加1,浅复制, 仅仅是指针的复制
    
    // 深复制
    NSString *str3 = [muStr copy];
    NSLog(@"muStr = %p, %@, count = %ld", muStr, muStr, [muStr retainCount]);
    // muStr = 0x100103920, name is lili, age is 28, count = 1
    NSLog(@"str3 = %p, %@, count = %ld", str3, str3, [str3 retainCount]);
    // str3 = 0x100204490, name is lili, age is 28, count = 1
    
    // 深复制
    NSMutableString *muStr2 = [muStr mutableCopy];
    NSLog(@"muStr = %p, %@, count = %ld", muStr, muStr, [muStr retainCount]);
    // muStr = 0x100103920, name is lili, age is 28, count = 1
    NSLog(@"muStr2 = %p, %@, count = %ld", muStr2, muStr2, [muStr2 retainCount]);
    // muStr2 = 0x1002044c0, name is lili, age is 28, count = 1
    
    
    [muStr2 release]; // 产生新对象,深复制, 要进行releae操作
    [str3 release];   // 产生新对象,深复制, 要进行releae操作
    [str2 release];   // 由于copy方法使源对象引用计数加1, 所以也要进行一次release操作
    [muStr release];  // 由mutableCopy产生的对象也要进行release操作
    [str release];
}


深浅复制图示


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值