OC-深淺復制

【OC學習-26】對象的淺拷貝和深拷貝——關鍵在于屬性是否可被拷貝

拷貝用到協議,如果這個類創建對象后,這個對象要被拷貝,那么這個類就需要用到拷貝協議,分兩種:<NSCopying>和<NSMutableCopying>相當于一個是拷貝,另一個是拷貝后可修改。

?

(1)淺拷貝的案例。有一個Person類,它創建一個person1對象后,用person1再拷貝一個person2出來。

//Person類的Person.h文件
#import <Foundation/Foundation.h>
//因為這個類要支持拷貝,所以需要引入拷貝協議,有兩種,后一種拷貝后可修改
@interface Person : NSObject<NSCopying,NSMutableCopying>
@property(nonatomic,copy) NSString* name; @property(nonatomic,retain) NSNumber* age; @end
//這是Person.m文件
#import "Person.h"
@implementation Person
//這是系統函數,可以直接拷貝過來 - (id)copyWithZone:(NSZone *)zone{  Person *person=[[[self class]allocWithZone:zone]init]; //默認格式  person.name=_name; //淺拷貝就是直接賦值即可  person.age=_age; //淺拷貝就是直接賦值即可  return person; } @end
//main.m文件
#import <Foundation/Foundation.h>
#import "Person.h"//記得引入頭文件
int main(int argc, const char * argv[])
{
 @autoreleasepool {   Person *person1=[[Person alloc]init];   person1.name=@"jack";   person1.age=@18;   Person *person2=[person1 copy];   NSLog(@"%p,%p",person1,person2);//輸入兩個對象地址,不同   NSLog(@"%p,%p",person1.age,person2.age);//輸出兩個對象的屬性地址,相同  }  return 0; }

結果:

0x1002036f0,0x100200330 //不同
0x1227,0x1227 //相同

(2)深拷貝的案例。

按道理是只需要把Person.m里面的賦值語句改成下面的樣子,就能實現深拷貝:

person.name=[_name copy]; 
person.age=[_age copy];

但是,因為cocoa優化過了,所以有如下規則:

a:如果是Foundation框架里的不可變對象,就是Array,NSString等創建的對象,直接用copy來拷貝相當于retain,也就是屬性還是同一個;

b:如果是用mutableCopy來拷貝,不管是可變還是不可變對象,屬性神馬的都直接拷貝了一份,即真正意義上得拷貝,它拷貝出來的對象統統都是可變的;

c:如果是可變對象,我們用copy也能實現真正意義上的拷貝,但是拷貝出來的對象是不可變的。

所以,我們拿name實驗(因為age沒有mutableCopy)實現語句的修改:

person.name=[_name mutableCopy]
person.age=[_age copy];

然后再輸出person1和person2的name屬性的地址,發現就不同了。

總結:

淺拷貝和深拷貝在實際項目中不常用,可以做一般了解。

?

?

?

OC-深淺復制

???淺 復?制:在復制操作時,對于被復制的對象的每一層復制都是指針復制。

???深 復?制:在復制操作時,對于被復制的對象至少有一層復制是對象復制。

???完全復制:在復制操作時,對于被復制的對象的每一層復制都是對象復制。

?

????????注:1在復制操作時,對于對象有n層是對象復制,我們可稱作n級深復制,此處n應大于等于1。

??????????????2對于完全復制如何實現(目前通用的辦法是:迭代法和歸檔),這里后續是否添加視情況而定,

??????????????暫時不做講解。

??????????3、指針復制俗稱指針拷貝,對象復制也俗稱內容拷貝。

?

retain:始終是淺復制。引用計數每次加一。返回對象是否可變與被復制的對象保持一致。

?

copy:對于可變對象為深復制,引用計數不改變;對于不可變對象是淺復制,

?????????引用計數每次加一。始終返回一個不可變對象。

?

mutableCopy:始終是深復制,引用計數不改變。始終返回一個可變對象。

?

不可變對象:值發生改變,其內存首地址隨之改變。

???可變對象:無論值是否改變,其內存首地址都不隨之改變。

???引用計數:為了讓使用者清楚的知道,該對象有多少個擁有者(即有多少個指針指向同一內存地址)。

?

親愛的讀者朋友,下面是我用于驗證的詳細代碼。對于驗證還能得出什么結論,我希望朋友們能自己多多發掘一下。這里只做以上幾點總結。對于本文有任何疑問請與我聯系,歡迎指出本文不足的地方,謝謝!

#import<Foundation/Foundation.h>

?

int?main (int?argc,?const?char?* argv[])

{

?

????@autoreleasepool?{

?

????//第一種:非容器類不可變對象

?

????????NSString?*str1=@"one day";

????????

??????????printf("n初始化賦值引用計數為::::%lu",str1.retainCount);

????????NSString?*strCopy1=[str1?retain];

??????????printf("n繼續retain引用計數為:::%lu",str1.retainCount);

????????NSString?*strCopy2=[str1?copy];

??????????printf("n繼續copy后引用計數為::::%lu",str1.retainCount);

????????NSString?*strCopy3=[str1?mutableCopy];

????????????????printf("n繼續mutableCopy后為:::%lun",str1.retainCount);

????????

????????printf("n非容器類不可變對象n原始地址::::::::::%p",str1);

????????printf("nretain復制::::::::%p",strCopy1);

????????printf("ncopy復制::::::::::%p",strCopy2);

????????printf("nmutableCopy復制:::%p",strCopy3);

?

????//這里說明該類型不存在引用計數的概念

?

??//?初始化賦值引用計數為:18446744073709551615

??//?繼續retain引用計數為:18446744073709551615

??//?繼續copy后引用計數為:18446744073709551615

??//?繼續mutableCopy后為:18446744073709551615

???

???//非容器類不可變對象

???//原始地址::::::::::0x1000033d0

???//retain復制::::::::0x1000033d0//淺復制

???//copy復制::::::::::0x1000033d0//淺復制

???//mutableCopy復制:::0x10010c420//深復制

??

?

??????printf("n");

?//第二種:容器類不可變數組

?

????????NSArray?*array1= [NSArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

????????

??????????printf("n初始化賦值引用計數為::::::::::::%lu",array1.retainCount);

????????NSArray?*arrayCopy1 = [array1?retain];

??????????printf("n繼續retain后引用計數為:::::::::%lu",array1.retainCount);

????????NSArray?*arrayCopy2 = [array1?copy];

??????????printf("n繼續copy后引用計數為:::::::::::%lu",array1.retainCount);

????????NSArray?*arrayCopy3 = [array1?mutableCopy];

??????????printf("n繼續mutableCopy后引用計數為::::%lun",array1.retainCount);

????????

????printf("n容器類不可變數組n原始地址::::::::::%ptt%p",array1,[array1 objectAtIndex:1]);

????????printf("nretain復制::::::::%pt%p",arrayCopy1,[arrayCopy1?objectAtIndex:1]);

????????printf("ncopy復制::::::::::%pt%p",arrayCopy2,[arrayCopy2?objectAtIndex:1]);

????????printf("nmutableCopy復制:::%pt%p",arrayCopy3,[arrayCopy3?objectAtIndex:1]);

????????

???

????//初始化賦值引用計數為::::::::::::1

????//繼續retain后引用計數為:::::::::2

????//繼續copy后引用計數為:::::::::::3

????//繼續mutableCopy后引用計數為::::3

?

????//容器類不可變數組

????//原始地址::::::::::0x10010c6b0 0x100003410

????//retain復制::::::::0x10010c6b0 0x100003410//淺復制

????//copy復制::::::::::0x10010c6b0 0x100003410//淺復制

????//mutableCopy復制:::0x10010c760 0x100003410//深復制

?

????

????????printf("n");

?//第三種:非容器類可變對象

?

????????NSMutableString?*str2=[NSMutableString?stringWithString:@"two day"];

????????

??????????printf("n初始化賦值引用計數為::::::::::::%lu",str2.retainCount);

????????NSMutableString?*strCpy1=[str2?retain];

??????????printf("n繼續retain后引用計數為:::::::::%lu",str2.retainCount);

????????NSMutableString?*strCpy2=[str2?copy];

??????????printf("n繼續copy后引用計數為:::::::::::%lu",str2.retainCount);

????????NSMutableString?*strCpy3=[str2?mutableCopy];

????????????????printf("n繼續mutableCopy后引用計數為::::%lun",str2.retainCount);

????????

????????printf("n非容器類可變對象n原始地址::::::::::%p",str2);

????????printf("nretin復制::::::::%p",strCpy1);

????????printf("ncopy復制::::::::::%p",strCpy2);

????????printf("nmutableCopy復制:::%p",strCpy3);

???????

?

?

?????????//初始化賦值引用計數為::::::::::::1

?????????//繼續retain后引用計數為:::::::::2

?????????//繼續copy后引用計數為:::::::::::2

?????????//繼續mutableCopy后引用計數為::::2

?

?????????//非容器類可變對象

?????????//原始地址::::::::::0x10010c560

?????????//retain復制::::::::0x10010c560//淺復制

?????????//copy復制::::::::::0x100102720//深復制

???????//mutableCopy復制:::0x10010c880//深復制

?????????

????????printf("n");

?//第四種:容器類可變數組

?

??NSMutableArray?*array2 ??= [NSMutableArrayarrayWithObjects:@"aa",@"bb",@"cc",@"dd",nil];

????????

?????????printf("n初始化賦值引用計數為::::::::::%lu",array2.retainCount);

???????NSMutableArray?*arrayCpy1 = [array2?retain];

?????????printf("n繼續retain后引用計數為:::::::%lu",array2.retainCount);

???????NSMutableArray?*arrayCpy2=[array2?copy];

?????????printf("n繼續copy后引用計數為:::::::::%lu",array2.retainCount);

???????NSMutableArray?*arrayCpy3 = [array2?mutableCopy];

?????????printf("n繼續mutableCopy后引用計數為::%lun",array2.retainCount);

????????

???????printf("n容器類可變數組n原始地址:::::::::::%pt%p",array2,[array2 objectAtIndex:1]);

???????printf("nretain復制:::::::::%pt%p",arrayCpy1,[arrayCpy1?objectAtIndex:1]);

???????printf("ncopy復制:::::::::::%pt%p",arrayCpy2,[arrayCpy2?objectAtIndex:1]);

???????printf("nnmutableCopy復制:::%pt%p",arrayCpy3,[arrayCpy3?objectAtIndex:1]);

???????

????????

?????????//初始化賦值引用計數為::::::::::1

?????????//繼續retain后引用計數為:::::::2

?????????//繼續copy后引用計數為:::::::::2

?????????//繼續mutableCopy后引用計數為::2

?

?????????//容器類可變數組

?????????//原始地址:::::::::::0x10010e6c0 0x1000034b0

?????????//retain復制:::::::::0x10010e6c0 0x1000034b0//淺復制

?????????//copy復制:::::::::::0x10010e790 0x1000034b0//深復制

?????????//nmutableCopy復制:::0x10010e7c0 0x1000034b0//深復制

?????????

????????

?

????}

????return 0;

}

?

轉載于:https://www.cnblogs.com/iOS-mt/p/4121583.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/376464.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/376464.shtml
英文地址,請注明出處:http://en.pswp.cn/news/376464.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

計算機科學導論(第一次閱讀)

時間&#xff1a; 2017年4月22日----2017年4月26 這是一本計算機入門書籍&#xff0c;粗略地描述了計算機各個方面的內容。當然對于一些十分復雜的知識&#xff0c;也僅僅是大概描述了這方面知識的一些了解知識。

配置SQLServer,允許遠程連接

需要別人遠程你的數據庫&#xff0c;首先需要的是在一個局域網內&#xff0c;或者連接的是同一個路由器&#xff0c;接下來就是具體步驟&#xff1a; &#xff08;一&#xff09;首先是要檢查SQLServer數據庫服務器中是否允許遠程鏈接。其具體操作為&#xff1a; &#xff08;1…

彈出打開/保存文件對話框 選擇文件夾對話框

打開/保存文件對話框: CFileDialog::CFileDialog(BOOL bOpenFileDialog, //為TRUE則顯示打開對話框&#xff0c;為FALSE則顯示保存對話文件對話框LPCTSTR lpszDefExt NULL, //默認的文件擴展名LPCTSTR lpszFileName NULL, //默認的文件名DWORD dwFlags OFN_HIDEREADONLY | O…

SharePoint 2013的100個新功能之網站管理(一)

一&#xff1a;設置盤 網站操作現在被替換為新的&#xff08;設置&#xff09;盤子。一些新的操作像添加一個應用、添加一個頁面或設計管理器被添加而像創建網站則從菜單中移除了。 二&#xff1a;移除以其他用戶身份登錄 在SharePoint 2013中&#xff0c;從用戶歡迎菜單中移除…

160 - 13 badboy

偷懶了很久也是時候要繼續開始學習了。 環境&#xff1a; windows xp sp3 工具&#xff1a; VB Decompiler v8.3 這次是個vb文件&#xff0c;所以嘗試一下用這個的感覺。 打開文件之后發現有兩個CrackMe選擇&#xff0c;分別是1.0版本和2.0版本。 打開vb decompiler&#…

VBS操作剪切板

VBS操作剪切板 設置剪切板的內容 Dim Form, TextBox Set Form CreateObject("Forms.Form.1") Set TextBox Form.Controls.Add("Forms.TextBox.1").Object TextBox.MultiLine True TextBox.Text "忘記了&#xff0c;喜歡一個人的感覺" TextBo…

MVN生成java項目

mvn archetype:create -DgroupIdcom.mycompany.app -DartifactIdmyWeb -DarchetypeArtifactIdmaven-archetype-webapp 轉載于:https://www.cnblogs.com/alaricblog/p/3278239.html

160 - 14 bjanes.1

環境&#xff1a; window xp sp3 工具&#xff1a; ollydbg &#xff0c;exeinfo pe 拿到程序后&#xff0c;查殼。顯示是無殼的VB程序 用之前用的VB decompiler載入&#xff0c;沒找到有用的東西&#xff0c;還是用回了OD。 OD載入&#xff0c;運行起來。輸入“GNUBD”然后點…

小結C++中一些自帶的好用東西

STL部分 <set>/<multiset> 支持插入一個元素&#xff0c;刪除指定key值的元素&#xff0c;查找指定key值的元素&#xff0c;返回最大/小值&#xff0c;找前驅&#xff0c;找后繼&#xff0c;返回指定key值的相同元素個數。 部分代替平衡樹中一些操作。不能updata或…

160 - 15 blaster99.exe

環境&#xff1a; windows xp sp 3 工具&#xff1a; Ollydbg 和 exeinfo pe 查殼&#xff0c;還是無殼的vb程序。 打開&#xff0c;有一個nag窗口&#xff0c;點擊”確認”的話才會彈出輸入serial的窗口&#xff0c;點“取消”的話會關閉程序 OD載入&#xff0c;運行到彈出n…

Freemarker宏和函數的用法和區別

1.宏&#xff08;macro&#xff09;寫法&#xff1a;<#macro page url page maskSize5> <#if (number pages)><li><a href"javascript:void(0);">下一頁</a></li><li><a href"javascript:void(0);">尾…

聚類算法初探(八)數據尺度化問題

文中尺度化的一些具體公式可參見 http://blog.csdn.net/itplus/article/details/10088101 其他相關鏈接 引言 預備知識 直接聚類法 K-means DBSCAN OPTICS 聚類分析的效果評測 作者: peghoty 出處: http://blog.csdn.net/itplus/article/details/10484553 歡迎轉載/分享, 但請…

160 - 16 bjanes.2

環境&#xff1a; windows xp sp3 工具&#xff1a; bjanes.2&#xff0c;HashCalc 這個和14題是一樣的&#xff0c;看名字就發現都是2.0A&#xff0c;然后用HashCalc來計算一下MD5&#xff0c;發現它們的值是相同的。 如果沒猜錯&#xff0c;應該就是在14題是被放錯題了。

HDU 1269

很水的TARJAN求強聯通圖的問題。 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm>using namespace std; const int N10010; const int M100010; int head[N],dfn[N],low[N],stack[N],st; struct Edge{int u,v;int nxt…

maven庫文件所在目錄

C:\Documents and Settings\jgzhang2\.m2\repository轉載于:https://www.cnblogs.com/yipihema/p/3289140.html

imul和mul的計算

imul是把操作數符號也算上的&#xff1a; 設 AL 0B4H BL 11H 執行 imul BL 后&#xff1a;AL 0FAF4 原因&#xff1a; imul是把符號也算上的&#xff0c;所以AL是某個數的補碼&#xff0c;故得AL -4C -76D&#xff0c;而BL 17D 是正數&#xff0c;相乘得-1292&#x…

【待完善】make: command not found,以及libtool.m4 and ltmain.sh have a version mismatch問題的解決方案...

之前為了使用一個庫&#xff0c;都是去下載源碼&#xff0c;然后根據開發者提供的README手動用GCC編譯&#xff0c;一直不能使用Makefile感覺很蛋痛&#xff0c;比如最近使用的ZThread 還是怪自己以前過于依賴IDE 最近發現用Cygwin就可以使用諸如./configure, make這樣的命令&a…

ubuntu 12.04 下安裝 MySQL 5.5

參考&#xff1a;http://www.linuxidc.com/Linux/2011-12/48920.htm《Ubuntu 11.04 通過 apt 安裝 MySQL 5.1 的全過程記錄》 說明&#xff1a;在mysql官網下載ubuntu下的安裝包進行安裝&#xff0c;不是一件容易的事。這里不是指下載&#xff0c;而是指安裝配置過程。 所以可以…

160 - 17 bjanes.3

環境&#xff1a; Wiondws XP sp3 工具&#xff1a; ollydbg&#xff0c;ExeInfo PE 查殼&#xff1a; 用Exeinfo PE 查殼&#xff0c;沒有殼&#xff0c;是VB寫的 過程&#xff1a; 一&#xff1a;隨便輸入一個serial&#xff0c;得到一個錯誤信息消息框&#xff0c;OD載入…

菜鳥nginx源碼剖析

菜鳥nginx源碼剖析 配置與部署篇&#xff08;一&#xff09; 手把手配置nginx “I love you” TCMalloc 對MYSQL 性能 優化的分析 菜鳥nginx源碼剖析系列文章解讀 Author&#xff1a;Echo Chen&#xff08;陳斌&#xff09; Email&#xff1a;chenb19870707gmail.com Blog&…