国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

copy,retain,strong的區(qū)別

2019-11-08 00:19:55
字體:
來源:轉載
供稿:網(wǎng)友

      之前的編碼中,對于NSString的PRoperty修飾,習慣性使用copy,只是粗略的知道copy屬于深復制,retain/strong屬于淺復制,并沒有對其深究。最近需要詳細了解這一塊知識,在網(wǎng)上搜索相關內(nèi)容,并且用代碼驗證,查看對比了內(nèi)存地址,做一些總結。

        一、之前對于copy和retain/strong的區(qū)別理解是這樣的:

        copy是復制了源對象所在內(nèi)存空間的數(shù)據(jù),放入目的對象指針指向的內(nèi)存空間,并且令目的對象引用計數(shù)為1,對于源對象的引用計數(shù)沒有影響;源對象內(nèi)容的改變不會影響到目的對象。

       retain/strong是目的對象指針指向源對象的內(nèi)存空間,源對象的引用計數(shù)+1;源對象的改變會影響到目的對象。

       

      mutablecopy返回的是可變的對象,copy返回的是不可變的對象。

       二、代碼驗證探究

     1、源對象為不可變 NSString

   

[objc] view plain copy 在CODE上查看代碼片NSString*str = @"test";  NSString* retainStr = [str retain];  NSString* copyStr = [str copy];  NSMutableString* mcopyStr = [str mutableCopy];  NSLog(@"str addr = %p",str);  NSLog(@"retainStr addr = %p",retainStr);  NSLog(@"copyStr addr = %p",copyStr);  NSLog(@"mcopyStr addr = %p",mcopyStr);  輸出如下:

       

[html] view%20plain copy str addr = 0x4598  retainStr addr = 0x4598  copyStr addr = 0x4598  mcopyStr addr = 0x8caf630  分析:

retain的對象毫無懸念,還是源對象的內(nèi)存地址;

copy的對象和我原來想的不一樣,竟然和retain一樣,也是源對象地址;這意味者并沒有對源對象內(nèi)容進行復制,而只是復制了指針而已。如此看來copy方法并不一定會復制源對象的內(nèi)容。之所以復制,肯定是因為兩個版本有所不同。而這里源對象是NSString不可變的,copy返回的也是不可變的,既然都不可變,那么這里的副本就沒有多大意義存在,就如同使用字符串常量,系統(tǒng)會為我們優(yōu)化,聲明多個字符串,都是不可變且內(nèi)容相同,那么系統(tǒng)就只申請一塊內(nèi)存,這個道理是一樣的。指向一塊內(nèi)存就可以了,所以這里的copy和retain的作用是一樣的。

mutablecopy的對象地址和源對象地址不同,說明重新開辟了內(nèi)存,復制了一個副本。因為mutablecopy返回的對象是可變的,它的變動會影響到源對象,所以需要拷貝一份。

源對象為可變的NSMutableString

[html] view%20plain copy NSMutableString* str = [NSMutableString stringWithString:@"test"];  NSString* retainStr = [str retain];  NSString* copyStr = [str copy];  NSMutableString* mcopyStr = [str mutableCopy];  NSLog(@"str addr = %p",str);  NSLog(@"retainStr addr = %p",retainStr);  NSLog(@"copyStr addr = %p",copyStr);  NSLog(@"mcopyStr addr = %p",mcopyStr);  輸出結果如下:

[html] view%20plain copy 派生到我的代碼片str addr = 0x8b7a130  retainStr addr = 0x8b7a130  copyStr addr = 0x8b751d0  mcopyStr addr = 0x8b7a170  

分析:

retain仍然和目的對象地址相同;

copy的地址和目的對象地址不相同,是因為源對象是可變的,目的對象不可變,當然需要兩個不同的版本;

mutablecopy形成了一個新的副本。因為兩個對象的改變會影響到對方,所以需要兩個版本。

得到的結論:

1、對于copy來說,如果源對象是不可變的,那么是淺拷貝,沒有必要深拷貝;如果源對象可變,為了安全性,深拷貝,生成副本。

2、對于mutablecopy來說,不管源對象是否可變,都是深拷貝。

因此我們在設置property的copy屬性時,如果希望對象跟著源對象的值變化,那么就是用retain;如果希望對象保持獨立的值,那就使用copy。當然這是在源對象為可變的情況下。

上面討論的是NSString相關的retain/copy/mutablecopy,在oc里面所有實現(xiàn)了NSCopying和NSMutableCopying協(xié)議的類,都具有copy和mutablecopy這兩個方法。這里引出了其他的oc對象的copy特性,它們是什么樣的,下一篇進行探究。

歡迎指正!  


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 乐昌市| 庄河市| 舞钢市| 舟曲县| 龙岩市| 延长县| 桐城市| 江川县| 贵南县| 长顺县| 江口县| 洞口县| 合川市| 安仁县| 仪陇县| 榆树市| 鸡泽县| 雷州市| 星座| 康定县| 海盐县| 新竹市| 沁阳市| 开阳县| 霍城县| 牡丹江市| 宁德市| 瓮安县| 永济市| 上犹县| 永顺县| 石渠县| 桐柏县| 萝北县| 衢州市| 通化市| 镇安县| 翼城县| 阳朔县| 沙河市| 杭锦旗|