標籤:
在這裡首先提及的就是定義屬性是用的屬性列表中的copy
@property(nonatomic,copy)NSString *name;
在這裡我定義了一個Person類,此處不再陳述
下面是代碼
Person *p = [[Person alloc] init];
NSMutableString *s = [[NSMutableString alloc] initWithFormat:@"123"];
p.name = s; //此時,name的值為@"123"
NSLog(@"**%@",p.name);
[s appendString:@"world"];
NSLog(@"%@",p.name);
NSLog(@"%p---%p",s,p.name);
輸出結果:
**123
123
0x100206e00---0x100206cf0
可以看出可變字串的值賦給了屬性name,但是地址變化了,在第一次輸出123後邊我又對s進行了重新賦值為world,但是並未影響到p.name的值,這也就驗證了地址確實不同了。其實它內部是通過
- (void)setName:(NSMutableString *)name
{
if(_name != name){ //判斷是否需要重新賦值
[_name release]; //釋放舊引用,計數器-1
_name = [name copy]; //重新賦值,使用copy********就是這裡*********
}
}
進行了深複製。因為s是可變數組,所以copy之後會開闢一個新的地址空間。假如s是不可變數組,那麼就會進行淺複製
假如把代碼改成:
Person *p = [[Person alloc] init];
NSString *s = @"123";
p.name = s; //此時,name的值為@"123"
NSLog(@"%@",p.name);
NSLog(@"%p---%p",s,p.name);
輸出結果:
123
0x100001068---0x100001068
地址是一樣的,說明進行了淺複製
總結:
copy:淺拷貝:不產生新的對象,直接指向原有對象(地址資料相同,雖然指標的名字不同) 拷貝出的結果是不可變對象,跟其接受類型沒有關係,跟其傳入類型也沒有關係
mutableCopy:深拷貝:產生新的對象,其內容是原有對象的內容,地址變了 拷貝的結果是可變對象,跟其傳入的類型沒有關係,但是會受其接收類型的影響
copy:被複製著是可變,則為深,否則為淺
NSString *s2 = [s1 copy];//八種情況中(s1:mutableString/String;s2:mutableString/String;copy/mutableCopy),只有s1為不可變和利用copy方法 同時滿足時為淺複製,其餘為深複製
//當使用NSCopy複製一個不可變對象時,其行為是淺複製,其餘情況都是深拷貝//當使用NSMutablecopy時,是深拷貝
那麼為什麼淺複製地址不變呢?
當被copy者類型是字串常量時(就是不可變字串),系統會為我們最佳化,聲明了多個字串, 但是都是常量,且內容相等,那麼系統就只為我們申請一塊空間。賦值過程:輸入資料→寄存器處理→開闢記憶體→寫入資料。一次深複製,可以得到被複製對象指標,並進行一次賦值操作。
Objective -C 之copy(複製)