pragma mark Copy基本使用(深淺拷貝)
pragma mark 概念
/**
一、copy基本概念
1.什么是copy
copy的字面意思 “復制”、“拷貝” 是一個產(chǎn)生副本的過程
2.常見的復制有: 文件復制
作用: 利用一個 源文件 產(chǎn)生一個副本文件
特點:
修改源文件的內(nèi)容,不會影響副本文件
修改副本文件的內(nèi)容, 不會影響文件
OC中的copy
作用:利用一個源對象 產(chǎn)生一個副本對象
特點:
修改源對象的 屬性 和 行為, 不會影響 副本對象
修改副本對象的 屬性 和 行為, 不會影響 源對象
二、copy的使用
如何使用copy功能
一個對象 可以調(diào)用copy 或者 mutableCopy 方法創(chuàng)建一個副本對象
copy: 創(chuàng)建的是 不可變副本 (如:NSString、NSArray、NSDictionary)
mutableCopy: 創(chuàng)建的是 可變副本(如:NSMutableString、NSMutableArray、NSMutableDictionary)
使用copy功能的前提
copy: 需要遵守 NSCopying協(xié)議,實現(xiàn)copyWithZone方法
@protocol NSCopying
- (id)copyWithZone:(NSZone *)zone;
@end
使用mutableCopy的前提
需要遵守NSMutableCopying協(xié)議,實現(xiàn)mutableCopyWithZone:方法
@protocol NSMutableCopying
- (id)mutableCopyWithZone:(NSZone *)zone;
@end
三、深復制、淺復制
(一句話 不可變 對 不可變 進行 copy 不產(chǎn)生新的對象 是淺拷貝)
(其他的 都會產(chǎn)生 新的對象 所以 都是深拷貝 )
---------------
(1....)淺復制 (淺拷貝,指針拷貝、shallow copy)
源對象 和 副本對象都是 同一個對象
源對象 (副本對象) 引用計數(shù)器 +1 , 相當于 做了 retain操作
本質(zhì) : 沒有產(chǎn)生新的對象
代碼 不可變 對 不可變 進行 copy
NSString *srcStr3 = @"lyhhh";
NSString *copyStr3 = [srcStr3 copy];
NSLog(@"4.淺拷貝 ---- %p,%p",srcStr3, copyStr3);
---------------
(2....)深復制 (深拷貝、內(nèi)存拷貝、deep copy)
源對象 和 副本對象是不同的兩個對象
源對象 引用計數(shù)器 不變 , 副本對象計數(shù)器 + 1 (因為是新產(chǎn)生的對象 )
本質(zhì) : 產(chǎn)生了新的對象
代碼1 不可變 對 可變 進行 mutableCopy
NSString *srcStr = @"lyh";
NSMutableString *copyStr = [srcStr mutableCopy]; // 調(diào)用 mutableCopy 會產(chǎn)生 一個 NSMutableString
NSLog(@"srcStr = %@,copyStr = %@",srcStr,copyStr);
NSLog(@"%p,%p",srcStr, copyStr);
NSLog(@"--------");
代碼2 可變 對 可變 進行 mutableCopy
NSMutableString *srcStr1 = [NSMutableString stringWithFormat:@"lyh"];
NSMutableString *copyStr1 = [srcStr1 mutableCopy];
[srcStr1 appendString:@" cool"];
NSLog(@"srcStr1 = %@,copyStr1 = %@",srcStr1,copyStr1);
NSLog(@"%p,%p",srcStr1, copyStr1);
NSLog(@"--------");
代碼3 可變 對 不可變 進行 copy
NSMutableString *srcStr2 = [NSMutableString stringWithFormat:@"lyh"];
NSString *copyStr2 = [srcStr2 copy];
[srcStr2 appendString:@" cool"];
NSLog(@"srcStr2 = %@,copyStr2 = %@",srcStr2,copyStr2);
NSLog(@"%p,%p",srcStr2, copyStr2);
NSLog(@"--------");
*/
pragma mark 代碼
#import <Foundation/Foundation.h>
#pragma mark 類
#pragma mark main函數(shù)
int main(int argc, const char * argv[])
{
#pragma Copy基本使用(深淺拷貝)
#pragma mark 深拷貝
#warning 1.
// 會生成一個新的對象
NSString *srcStr = @"lyh";
// 只要是 拷貝出來的對象, 拷貝出來的對象 的內(nèi)容 和 以前對象中的內(nèi)容一致
// "一般"情況 拷貝會生成一個新的對象
// 為什么會產(chǎn)生 一個新的對象 1.因為 拷貝 要求修改原來的對象 不能影響到 拷貝出來的對象 \
修改拷貝出來的對象 也不能影響到 原來的對象, 所以需要生成 一個新的對象 \
2. 由于 以前的對象 是 一個不可變的對象, 而通過mutableCopy 拷貝出來的對象 必須 是一個可變的對象,所以必須生成一個新的對象
NSMutableString *copyStr = [srcStr mutableCopy]; // 調(diào)用 mutableCopy 會產(chǎn)生 一個 NSMutableString
NSLog(@"srcStr = %@,copyStr = %@",srcStr,copyStr);
NSLog(@"%p,%p",srcStr, copyStr);
NSLog(@"--------");
#warning 2.
// 會生成一個新的對象
NSMutableString *srcStr1 = [NSMutableString stringWithFormat:@"lyh"];
NSMutableString *copyStr1 = [srcStr1 mutableCopy];
[srcStr1 appendString:@" cool"];
NSLog(@"srcStr1 = %@,copyStr1 = %@",srcStr1,copyStr1);
NSLog(@"%p,%p",srcStr1, copyStr1);
NSLog(@"--------");
#warning 3.
// 會生成一個新的對象
NSMutableString *srcStr2 = [NSMutableString stringWithFormat:@"lyh"];
NSString *copyStr2 = [srcStr2 copy];
[srcStr2 appendString:@" cool"];
NSLog(@"srcStr2 = %@,copyStr2 = %@",srcStr2,copyStr2);
NSLog(@"%p,%p",srcStr2, copyStr2);
NSLog(@"--------");
#pragma mark 淺拷貝
#warning 4.
/**
正是 因為調(diào)用copy方法有時候會生成 一個新的對象, 有時候不會生成 一個新的對象
所以 : 如果沒有生成 新的對象 , 我們稱之為 淺拷貝, (本質(zhì) 就是 指針拷貝)
如果生成了新的對象, 我們陳志偉 深拷貝 , 本質(zhì)就是 會創(chuàng)建一個新的對象
*/
// 如果是 通過 不可變對象 調(diào)用了 copy, 那么不會生成一個新的對象
// 原因: 因為 原來的對象 是不能修改的, 拷貝出來的對象 也是不能修改的
// 既然 兩個都不能修改, 所以 永遠不能影響到 另外一個對象, 那么已經(jīng)符合需求了
// 所以 : OC為了對 內(nèi)容進行優(yōu)化, 就不會生成一個新的對象
NSString *srcStr3 = @"lyhhh";
NSString *copyStr3 = [srcStr3 copy];
NSLog(@"4.淺拷貝 ---- %p,%p",srcStr3, copyStr3);
return 0;
}