在 iOS 中,最為重要的一點就是內(nèi)存管理,。而在內(nèi)存管理時,,有時會遇到 copy 出來的對象,是否需要釋放內(nèi)存的情況,。所以,,本文將講解下 copy 與 mutableCopy 的用法和區(qū)別。
環(huán)境信息:
Mac OS X 10.9
Xcode 5.1.1
正文:
關(guān)閉 ARC 模式
以下所有內(nèi)容都將以 NSString 作為例子進行講解
copy 出來的對象都是不可變對象
// 對于不可變字符串,,copy 類似與 retain(淺copy)
NSString *string1 = [[NSString alloc] initWithFormat:@"字符串1"];
NSString *newString1 = [string1 copy];
NSLog(@"%ld", [string1 retainCount]); //2
不可變字符串(字典、集等),,copy 操作相當于 retain (指針拷貝),。
這種 copy 方式,不會分配內(nèi)存,,只是讓 newString1 持有了 string1 的內(nèi)存,。
// 對于可變字符串,copy 會重新開辟空間(深 copy)
NSMutableString *string2 = [[NSMutableString alloc] initWithFormat:@"字符串2"];
NSMutableString *newString2 = [string2 copy];
NSLog(@"%ld", [string2 retainCount]); //1
可變字符串(字典,、集等),,copy 操作相當于 alloc 并且賦值(內(nèi)存拷貝)。這種 copy 方式,,會重新分配內(nèi)存,。
所以對 newString2 操作(修改、release 等)并不會影響到 string2 ,,因為他們沒有在操作同一塊內(nèi)存,。
因為 copy 出來的都是不可變對象,所以這里的 newString2 ,,即使是 NSMutableString 類型,,但不能調(diào)用可變對象的方法,因為 newString2 已經(jīng)是不可變對象了,。
如果強制調(diào)用,,程序崩潰,并報錯:‘Attempt to mutate immutable object with deleteCharactersInRange:…’ 試圖修改一個不可變的對象
mutableCopy 復制出來的對象都是可變對象,,并且對于 NSString 和 NSMutableString 都是內(nèi)存拷貝(深copy)
// 對于不可變和可變對象,,都是內(nèi)容復制(深 copy)
NSString *string3 = [[NSString alloc] initWithFormat:@"字符串3"];
NSString *newString3 = [string3 mutableCopy];
NSLog(@"%ld", [string3 retainCount]); //1
雖然使用了 NSString 去接收了 mutableCopy 出來的 string3 ,但是 newString3 依然是一個可變字符串,,可以調(diào)用可變字符串的方法,,但是會報警告,,因為子類調(diào)用了父類的方法。
NSMutableString *string4 = [[NSMutableString alloc] initWithFormat:@"字符串4"];
NSMutableString *newString4 = [string4 mutableCopy];
NSLog(@"%ld", [string4 retainCount]); // 1
對于可變字符串,,mutableCopy 依然是可變,。
總結(jié):
|