//非容器類物件
nsstring *str = @"
origin string";
nsstring *strcopy =[str copy];
nsmutablestring *mstrcopy =[str mutablecopy];
@"??"];
//nslog(@"array1 = %p", array1);
//nslog(@"arraycopy1 = %p", arraycopy1);
檢視記憶體可以發現,str和strcopy指向的是同一塊記憶體區域,我們稱之為弱引用(weak reference)。而mstrcopy是真正的複製,系統為其分配了新記憶體空間,儲存從str複製過來的字串值。從最後一行**中修改這些值而不影 響str和strcopy中可證明。
示例2:
nsmutablestring *mstr = [nsmutablestring stringwithstring:@"origin"];
nsstring *strcopy =[mstr copy];
nsmutablestring *mstrcopy =[mstr copy];
nsmutablestring *mstrmcopy =[mstr mutablecopy];
////
error
222"
];@"
333"];
以上四個物件所分配的記憶體都是不一樣的。而且對於mstrcopy,它所指向的其實是乙個imutable物件,是不可改變的,所以會出錯。這點要注意,好好理解。
示例3:
/*copy返回不可變物件,mutablecopy返回可變物件
*/nsarray *array1 = [nsarray arraywithobjects:@"
a",@"
b",@"c"
,nil];
nsarray *arraycopy1 =[array1 copy];
//arraycopy1是和array同乙個nsarray物件(指向相同的物件),包括array裡面的元素也是指向相同的指標
nslog(@"
array1 retain count: %d
",[array1 retaincount]); // 2
nslog(
@"array1 retain count: %d
",[arraycopy1 retaincount]); // 2
nsmutablearray *marraycopy1 =[array1 mutablecopy];
//marraycopy1是array1的可變副本,指向的物件和array1不同,但是其中的元素和array1中的元素指向的還是同乙個物件。marraycopy1還可以修改自己的物件
[marraycopy1 addobject:@"de"
]; [marraycopy1 removeobjectatindex:
0];
array1和arraycopy1是指標複製,而marraycopy1是物件複製,符合前面示例1討論的結論。marraycopy1可以改變其內的元素:刪除或新增。但容器內的元素內容都是淺拷貝。
示例4
nsarray *marray1 = [nsarray arraywithobjects:[nsmutablestring stringwithstring:@"a"],@"
b",@"c"
,nil];
nslog(
@"marray1 retain count: %d
",[marray1 retaincount]);
nsarray *marraycopy2 =[marray1 copy];
nslog(
@"marray1 retain count: %d
",[marray1 retaincount]);
//marray1和marraycopy2指向同一物件,retain值+1。
nsmutablearray *marraymcopy1 =[marray1 mutablecopy];
nslog(
@"marray1 retain count: %d
",[marray1 retaincount]);
//marraycopy2和marray1指向的是不一樣的物件,但是其中的元素都是一樣的物件——同乙個指標
nsmutablestring *teststring = [marray1 objectatindex:0
];
//teststring = @"1a1";
//這樣會改變teststring的指標,其實是將@「1a1」臨時物件賦給了teststring
tail
"];//
這樣以上三個陣列的首元素都被改變了
由此可見,對於容器而言,其元素物件始終是指標複製。如果需要元素物件也是物件複製,就需要實現深拷貝。
示例5
nsarray *array = [nsarray arraywithobjects:[nsmutablestring stringwithstring:@"first
"] ,[nsstring stringwithstring:@"
b"],@"c"
,nil];
nsarray *deepcopyarray=[[nsarray alloc] initwitharray: array copyitems: yes];
nslog(
@"array[2] = %@, deepcopyarray[2]=%@
",[array objectatindex:2], [deepcopyarray objectatindex:2]); //
輸出值是一樣的
nslog(@"
array[2] %p
", [array objectatindex:2
]);nslog(
@"deepcopyarray[2] %p
", [deepcopyarray objectatindex:2
]);
//最後兩個列印的log記憶體位址值是一樣的
nsarray* truedeepcopyarray =[nskeyedunarchiver unarchiveobjectwithdata:[nskeyedarchiver archiveddatawithrootobject: array]];
truedeepcopyarray 是完全意義上的深拷貝,而deepcopyarray則不是,對於 deepcopyarray 內的不可變元素其還是指標複製。
#import@inte***ce
nsdictionary(mutabledeepcopy)
- (nsmutabledictionary *)mutabledeepcopy;
@end
nsdictionarymutabledeepcopy.m
#import"nsdictionarymutabledeepcopy.h
"@implementation
nsdictionary(mutabledeepcopy)
- (nsmutabledictionary *)mutabledeepcopy
else
if([onevalue respondstoselector:@selector(mutablecopy)])
if (onecopy ==nil)
[ret setvalue:onecopy forkey:key];
}return
ret;
}
@inte***ce myobj : nsobject@property (nonatomic, retain) nsmutablestring *name;
@property (nonatomic, retain) nsstring *imutablestr;
@property (nonatomic)
intage;
@end
@implementation
myobj
@synthesize
name;
@synthesize
age;
@synthesize
imutablestr;
- (id
)init
return
self;
}- (void
)dealloc
- (id)copywithzone:(nszone *)zone
- (id)mutablecopywithzone:(nszone *)zone
@end
ios學習路線
sel在objective c中,sel是選擇器 selector 的乙個型別。選擇器就是指向方法的乙個指標,讀者可以簡單理解為程式執行到這裡就會執行指定的方法,可以這樣定義乙個選擇器 sel action button action 我們這樣使用乙個選擇器,下面的選擇器都叫做action foo ...
ios學習路線 Objective C MRC
reference count引用計數 cocoa採用了引用計數機制,每乙個物件有乙個關聯的整型retaincount用於記錄物件的使用情況。物件被引用時retaincount 1,外部環境結束物件的使用後retaincount 1,當 retaincount為0的時候,該物件被銷毀。objecti...
ios學習路線與計畫
非常感謝這張圖的作者,一張圖省了多少事,提高了多少效率,看這張圖ios的學習路線就基本知道了。另外再參考一下下面另一位前人的總結 1 第一點要求 能比較順暢的閱讀官方的文件 英語學習是個長期的過程,推薦一篇好文,具體教你如何學習和提高英語 老碼農教你學英語 2 學習官方的一些技術指南 這裡各種技術模...