#pragma mark - 拷貝的概念
/*
概念:是指對(duì)源對(duì)象進(jìn)行拷貝操作固阁,產(chǎn)生一個(gè)新的副本對(duì)象骑疆,這個(gè)副本對(duì)象與源對(duì)象互不影響兜蠕,相互獨(dú)立.
*/
// 備注:只有對(duì)不可變對(duì)象進(jìn)行copy操作, 才是指針拷貝, 即淺拷貝;
// 備注:使用mutableCopy進(jìn)行拷貝操作, 都是內(nèi)容拷貝, 即深拷貝;
#pragma mark - copy
/// copy
- (void)copyMethod
{
#pragma mark - 非集合類
// MARK: 不可變對(duì)象
/**
額外知識(shí)點(diǎn):tagged pointer對(duì)象
如何識(shí)別當(dāng)前對(duì)象為tagged pointer 對(duì)象粥惧?
答:查看當(dāng)前對(duì)象地址厉斟,iOS平臺(tái)下螃壤,二進(jìn)制最高有效位為1則是赐劣,否則不是映九; MacOS平臺(tái)下嫉到,二進(jìn)制最低有效位為則是沃暗;
*/
/* 字符串長(zhǎng)一點(diǎn), 避免初始化一個(gè)tagged pointer 對(duì)象, 查看引用計(jì)數(shù)的時(shí)候產(chǎn)生最大值 */
NSString *string = [NSString stringWithFormat:@"123,123,123,123,123,"];
NSString *string_c = string.copy; // 淺拷貝
NSLog(@"s: %p, c: %p", string, string_c);
// FIXME: 結(jié)論1.1
/**
淺拷貝產(chǎn)生的副本與源對(duì)象地址相同, 此時(shí)源對(duì)象的引用計(jì)數(shù)+1. 副本的引用計(jì)數(shù)與源對(duì)象的引用計(jì)數(shù)相同
*/
// 1. 嘗試修改string_c 的值, 查看是否會(huì)影響string的值
string_c = @"abcd,abcd,abcd,abcd";
NSLog(@"string: %@, string_c: %@", string, string_c);
// FIXME: 結(jié)論1.2
/**
結(jié)論:不會(huì)影響源對(duì)象string, 因?yàn)閏opy操作產(chǎn)生的副本對(duì)源對(duì)象不產(chǎn)生影響, 同時(shí) string_c的地址會(huì)發(fā)生改變.
*/
// 2. 嘗試使用strong修飾, 查看引用計(jì)數(shù)及修改值后對(duì)源對(duì)象的影響
_string_s = string;
string = @"111222333444";
NSLog(@"地址: string: %p, string_s: %p. 值: string: %@, string_s: %@", string, _string_s, string, _string_s);
// FIXME: 結(jié)論1.3
/**
結(jié)論:修改不可變類型 string的值, 不會(huì)影響_string_s的值. 即 修飾不可變類型使用copy與strong效果等同.
*/
// MARK: 可變對(duì)象
NSMutableString *string_M = [NSMutableString stringWithString:@"123,123,123,123,123,"];
NSMutableString *string_M_c = string_M.copy;
NSLog(@"s: %p, c: %p, class: %@", string_M, string_M_c, [string_M_c class]);
// FIXME: 結(jié)論1.4
/**
結(jié)論:不論是可變對(duì)象or不可變對(duì)象進(jìn)行copy操作后,都會(huì)產(chǎn)生一個(gè)不可變類型的對(duì)象.
*/
// 嘗試:當(dāng)修改strong修飾的可變類型的對(duì)象值時(shí), 會(huì)產(chǎn)生怎樣的影響何恶?
_string_M_s = string_M;
[_string_M_s appendFormat:@"改了哦"];
NSLog(@"string_M_s: %p, %@; string_M: %p, %@", _string_M_s, _string_M_s, string_M, string_M);
// FIXME: 結(jié)論1.5
/**
結(jié)論:當(dāng)修改strong修飾的可變類型的對(duì)象值時(shí), 被其引用的對(duì)象值也會(huì)被修改. 故平時(shí)開(kāi)發(fā)時(shí), 可變類型的對(duì)象修飾關(guān)鍵字沒(méi)有特殊需求盡量使用copy修飾, 避免在未知情況下, 導(dǎo)致源數(shù)據(jù)被修改而未被發(fā)現(xiàn), 導(dǎo)致產(chǎn)生不必要的事故.
*/
#pragma mark - 集合類對(duì)象
// MARK: 不可變對(duì)象
// NSArray, NSDictionary, NSSet, etc.
/**
與非集合類對(duì)象的不同點(diǎn)在于, 集合類對(duì)象中的元素不發(fā)生變化, 只有集合對(duì)象遵守copy規(guī)則.
*/
/// e.g.
NSNumber *n1 = @(1);
NSNumber *n2 = @(2);
NSNumber *n3 = @(3);
NSLog(@"before: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
NSArray *array = @[n1, n2, n3];
NSArray *array_c = array.copy;
NSLog(@"s: %p, c: %p", array, array_c);
/**
同結(jié)論1.1
結(jié)論:copy不可變類型, 產(chǎn)生的副本與源對(duì)象地址相同, 即副本的指針指向源對(duì)象, 即淺拷貝.
*/
NSLog(@"after: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
// FIXME: 結(jié)論1.6
/**
結(jié)論:copy不會(huì)對(duì)集合類的對(duì)象內(nèi)部元素產(chǎn)生影響.
*/
// MARK: 可變對(duì)象
NSMutableArray *array_M = [NSMutableArray arrayWithObjects:n1, n2, n3, nil];
NSMutableArray *array_M_c = array_M.copy;
NSLog(@"s: %p, c: %p", array_M, array_M_c);
/**
同結(jié)論1.4
結(jié)論:copy可變類型, 產(chǎn)生的副本與源對(duì)象地址不同, 內(nèi)容相同, 即深拷貝(內(nèi)容拷貝).
*/
NSLog(@"after: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
/**
同結(jié)論1.6
結(jié)論:copy不會(huì)對(duì)集合類的對(duì)象內(nèi)部元素產(chǎn)生影響.
*/
}
#pragma mark - mutableCopy
- (void)mutableCopyMethod
{
#pragma mark - 非集合類
// MARK: 不可變對(duì)象
NSString *string = [NSString stringWithFormat:@"123,123,123,123,123,"];
NSString *string_c = string.mutableCopy; // 深拷貝
NSLog(@"s: %p, c: %p, class: %@", string, string_c, [string_c class]);
// FIXME: 結(jié)論2.1
/**
結(jié)論:mutalbeCopy產(chǎn)生的副本與源對(duì)象地址不同, 內(nèi)容相同且是可變類型的對(duì)象, 即深拷貝.
*/
// MARK: 可變對(duì)象
NSMutableString *string_M = [NSMutableString stringWithString:@"123,123,123,123,123,"];
NSMutableString *string_M_c = string_M.mutableCopy;
NSLog(@"s: %p, c: %p, class: %@", string_M, string_M_c, [string_M_c class]);
// FIXME: 結(jié)論2.2
/**
結(jié)論:不論是可變對(duì)象or不可變對(duì)象進(jìn)行mutableCopy操作后孽锥,都會(huì)開(kāi)辟一塊新的內(nèi)存, 且產(chǎn)生一個(gè)可變類型的對(duì)象.
*/
#pragma mark - 集合類對(duì)象
// MARK: 不可變對(duì)象
// NSArray, NSDictionary, NSSet, etc.
/**
與非集合類對(duì)象的不同點(diǎn)在于, 集合類對(duì)象中的元素不發(fā)生變化, 只有集合對(duì)象遵守copy規(guī)則.
*/
/// e.g.
NSNumber *n1 = @(1);
NSNumber *n2 = @(2);
NSNumber *n3 = @(3);
NSLog(@"before: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
NSArray *array = @[n1, n2, n3];
NSArray *array_c = array.mutableCopy;
NSLog(@"s: %p, c: %p, class: %@", array, array_c, [array_c class]);
/**
同結(jié)論2.1
結(jié)論:mutalbeCopy產(chǎn)生的副本與源對(duì)象地址不同, 內(nèi)容相同且是可變類型的對(duì)象, 即深拷貝.
*/
NSLog(@"after: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
/**
同結(jié)論1.6
結(jié)論:mutalbeCopy不會(huì)對(duì)集合類的對(duì)象內(nèi)部元素產(chǎn)生影響.
*/
// MARK: 可變對(duì)象
NSMutableArray *array_M = [NSMutableArray arrayWithObjects:n1, n2, n3, nil];
NSMutableArray *array_M_c = array_M.copy;
NSLog(@"s: %p, c: %p", array_M, array_M_c);
/**
同結(jié)論2.1
結(jié)論:copy可變類型, 產(chǎn)生的副本與源對(duì)象地址不同, 內(nèi)容相同, 即深拷貝(內(nèi)容拷貝).
*/
NSLog(@"after: n1 = %p, n2 = %p, n3 = %p", n1, n2, n3);
/**
同結(jié)論1.6
結(jié)論:copy不會(huì)對(duì)集合類的對(duì)象內(nèi)部元素產(chǎn)生影響.
*/
}