copy的內(nèi)存管理
首先理解一下深復(fù)制和淺復(fù)制:
- 深復(fù)制
源對象和副本對象是不同的兩個(gè)對象藕甩;
源對象引用計(jì)數(shù)器不變剩瓶,副本對象計(jì)數(shù)器為1(因?yàn)槭切庐a(chǎn)生的)锋叨;
本質(zhì)是:產(chǎn)生了新的對象孩擂。 - 淺復(fù)制
源對象和副本對象是同一個(gè)對象
源對象(副本對象)引用計(jì)數(shù)器+1砰碴,相當(dāng)于做一次retain操作跪呈;
本質(zhì)是:沒有產(chǎn)生新對象钧敞。
注意:只有源對象和副本對象都不可變時(shí)蘸嘶,才是淺拷貝默怨,其他都是深拷貝
NSString *str1 = [NSString stringWithFormat:@"address is only one"];
NSString *str2 = [str1 copy];
NSLog(@"%p ,%p",str1,str2);
//結(jié)果發(fā)現(xiàn)兩個(gè)地址一樣布疙,都是0x610000052990豺瘤。
/**
1.copy:產(chǎn)生的肯定是不可變副本
2. 如果是不可變對象調(diào)用copy方法產(chǎn)生出不可變副本姆钉,那么不會(huì)產(chǎn)生新的對象
*/
1. NSMutableString調(diào)用mutableCopy : 深復(fù)制说订。
2. NSMutableString調(diào)用copy : 深復(fù)制。
3. NSString調(diào)用mutableCopy : 深復(fù)制育韩。
4. NSString調(diào)用copy : 淺復(fù)制
__strong
當(dāng)一個(gè)對象被強(qiáng)指針指向則引用計(jì)數(shù)就加1克蚂,否則,該對象沒有一個(gè)強(qiáng)指針指向則自動(dòng)釋放內(nèi)存
原理:
__weak
id __weak obj = [[NSObject alloc] init];
可以知道NSObject對象在生成之后立馬就會(huì)被釋放筋讨,其主要原因是__weak修飾的指針沒有引起對象內(nèi)部的引用計(jì)數(shù)器的變化
原理:
- 修飾的指針不會(huì)引起指向的對象的引用計(jì)數(shù)器變化
id obj;
id tmp = objc_msgSend(NSObject,@selector(alloc));
objc_msgSend(tmp,@selector(init));
objc_initweak(&obj,tmp);
objc_release(tmp);
objc_destroyWeak(&object);
對于__weak內(nèi)存管理也借助了類似于引用計(jì)數(shù)表的表埃叭,它通過對象的內(nèi)存地址做為key,而對應(yīng)的指針作為value進(jìn)行管理悉罕,在上述代碼中objc_initweak就是完成這部分操作赤屋,而objc_destroyWeak
則是銷毀該對象對應(yīng)的value立镶。所以,weak在修飾只是讓weak表增加了記錄沒有引起引用計(jì)數(shù)表的變化
- 當(dāng)指向的對象被銷毀時(shí)类早,弱指針全部置為nil
原理:
1)從weak表中獲取已廢棄對象內(nèi)存地址對應(yīng)的所有記錄
2)將已廢棄對象內(nèi)存地址對應(yīng)的記錄中所有以weak修飾的變量都置為nil
3)從weak表刪除已廢棄對象內(nèi)存地址對應(yīng)的記錄
4)根據(jù)已廢棄對象內(nèi)存地址從引用計(jì)數(shù)表中找到對應(yīng)記錄刪除