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];
}
深浅复制图示