NSMutableString
- “_”方式調用賦值
NSMutableString *mOriginMutableString = [[NSMutableString alloc] initWithString: @"原始數據"];
_mCopyMutableString = mOriginMutableString;
_mStrongMutableString = mOriginMutableString;
_mWeakMutableString = mOriginMutableString;
_mAssignMutableString = mOriginMutableString;
NSLog(@"mOriginMutableString : %p, %@", mOriginMutableString,mOriginMutableString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyMutableString,_mCopyMutableString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongMutableString,_mStrongMutableString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakMutableString,_mWeakMutableString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignMutableString,_mAssignMutableString);
NSLog(@"引用計數:%@", [mOriginMutableString valueForKey: @"retainCount"]);
運行結果圖如下:
有結果圖,我們發現,賦值後,引用計數爲3,指針相同。
- 通過“self.”的方式調用賦值
self.mCopyMutableString = mOriginMutableString;
self.mStrongMutableString = mOriginMutableString;
self.mWeakMutableString = mOriginMutableString;
self.mAssignMutableString = mOriginMutableString;
結果如圖如下:
我們發現引用計數爲2了,這是爲什麼呢?
因爲“self.” 會調用getter、setter方法,“_”方式不會調用getter、setter方法,直接訪問實例變量並賦值。
strong 指向原來的內存,並且指針數+1,
week 指向原來的內存,並且指針數不變,
assign指向原來的內存,但是指針數不變。
copy來說,如果是self. 調用是深拷貝,重新開闢內存塊,修改原來的值,不會導致現有值改變。
如果是_直接訪問,則相當於淺拷貝,指向原來的內存,指數+1。修改原來的值,會影響到現有的值。
week 與 assign來說
week內存釋放後,指針變爲nil
assign內存釋放後,指針不爲nil,後期數據改變後,出現野指針,導致程序崩潰
retain 與 strong爲同樣的功能,retain爲ARC出現之前的關鍵字。
增加指針爲強引用,不增加指針是弱引用
重新開闢內存塊是深拷貝,使用同一個內存塊爲淺拷貝
NSMutableArray
- 通過“self.”賦值。
NSMutableArray *mOriginMutableArray = [[NSMutableArray alloc] init];
NSMutableString *m1 = [[NSMutableString alloc] initWithString: @"原始數據 1"];
NSMutableString *m2 = [[NSMutableString alloc] initWithString: @"原始數據 2"];
NSMutableString *m3 = [[NSMutableString alloc] initWithString: @"原始數據 3"];
[mOriginMutableArray addObject:m1];
[mOriginMutableArray addObject:m2];
[mOriginMutableArray addObject:m3];
self.mCopyMutableArray = mOriginMutableArray;
self.mStrongMutableArray = mOriginMutableArray;
self.mWeakMutableArray = mOriginMutableArray;
NSLog(@"mOriginMutableArray : %p, %@", mOriginMutableArray,mOriginMutableArray);
NSLog(@"mCopyMutableArray : %p, %@", _mCopyMutableArray,_mCopyMutableArray);
NSLog(@"mStrongMutableArray: %p, %@", _mStrongMutableArray,_mStrongMutableArray);
NSLog(@"mWeakMutableArray : %p, %@", _mWeakMutableArray,_mWeakMutableArray);
NSLog(@"引用計數:%@", [mOriginMutableArray valueForKey: @"retainCount"]);
NSLog(@"%p %p %p %p", &mOriginMutableArray,mOriginMutableArray,mOriginMutableArray[0],mOriginMutableArray[1]);
結果圖如下:
- 採用“_”方式調用賦值
_mCopyMutableArray = mOriginMutableArray;
_mStrongMutableArray = mOriginMutableArray;
_mWeakMutableArray = mOriginMutableArray;
結果圖如下:
我們發現引用計數減少的原因和上邊的一樣,即self. 和_ 調用對copy的影響。
NSMutableArray類的addObject方法,對同一個對象執行N次,這這個對象的指針數就會加上N次,所以我們發現,使用_直接調用時,指針數爲2,而不是一。
copy同上邊的一樣,會重新開闢內存區域,strong、weak和原數據指向同一塊內存區域,
所以,copy是深拷貝,strong、weak、assign爲淺拷貝。
同時,我們修改數組中的元素時,發現,所有的數據元素都變了, 也就是說,數組中的NSMutableString在拷貝時是淺拷貝。
NSString
- “self.”調用
NSString *mOriginString = @"原始數據";
self.mCopyString = mOriginString;
self.mStrongString = mOriginString;
self.mWeakString = mOriginString;
self.mAssignString = mOriginString;
NSLog(@"mOriginMutableString : %p, %@", mOriginString,mOriginString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyString,_mCopyString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongString,_mStrongString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakString,_mWeakString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignString,_mAssignString);
NSLog(@"引用計數:%@", [mOriginString valueForKey: @"retainCount"]);
NSLog(@"-------------改變值後------------");
mOriginString = @"新值";
NSLog(@"mOriginMutableString : %p, %@", mOriginString,mOriginString);
NSLog(@"_mCopyMutableString : %p, %@", _mCopyString,_mCopyString);
NSLog(@"_mStrongMutableString: %p, %@", _mStrongString,_mStrongString);
NSLog(@"_mWeakMutableString : %p, %@", _mWeakString,_mWeakString);
NSLog(@"_mAssignMutableString: %p, %@", _mAssignString,_mAssignString);
NSLog(@"引用計數:%@", [mOriginString valueForKey: @"retainCount"]);
結果圖如下:
2. “_”調用
_mCopyString = mOriginString;
_mStrongString = mOriginString;
_mWeakString = mOriginString;
_mAssignString = mOriginString;
結果圖如下:
這個比較好理解,直接說結論了:
NSString 和 NSMutableString 基本相同,除了copy,對NSString來說是淺拷貝,對NSMutableString來說是深拷貝。
同時,我們發現通過self. 和 _ 調用,對copy來說都是一樣的,都是淺拷貝。
NSArray
NSString *m1 = @"Origin 1";
NSString *m2 = @"Origin 2";
NSString *m3 = @"Origin 3";
NSArray *mOriginArray = @[m1,m2,m3];
// self.mCopyArray = mOriginArray;
// self.mStrongArray = mOriginArray;
// self.mWeakArray = mOriginArray;
_mCopyArray = mOriginArray;
_mStrongArray = mOriginArray;
_mWeakArray = mOriginArray;
NSLog(@"mOriginArray : %p, %@", mOriginArray,mOriginArray);
NSLog(@"_mCopyArray : %p, %@", _mCopyArray,_mCopyArray);
NSLog(@"_mStrongArray: %p, %@", _mStrongArray,_mStrongArray);
NSLog(@"_mWeakArray : %p, %@", _mWeakArray,_mWeakArray);
NSLog(@"_mWeakArray[0] : %p, %@", mOriginArray[0],mOriginArray[0]);
NSLog(@"引用計數:%@", [mOriginArray valueForKey: @"retainCount"]);
NSLog(@"m1 修改前 : %p, %@", m1,m1);
m1 = @"NEW";
NSLog(@"m1 修改後 : %p, %@", m1,m1);
NSLog(@"_mWeakArray[0] : %p, %@", mOriginArray[0],mOriginArray[0]);
NSLog(@"mOriginArray : %p, %@", mOriginArray,mOriginArray);
NSLog(@"_mCopyArray : %p, %@", _mCopyArray,_mCopyArray);
NSLog(@"_mStrongArray: %p, %@", _mStrongArray,_mStrongArray);
NSLog(@"_mWeakArray : %p, %@", _mWeakArray,_mWeakArray);
NSLog(@"引用計數:%@", [mOriginArray valueForKey: @"retainCount"]);
我們可以發現,NSArray對其賦值時,他是進行的深拷貝,上邊的輸出,m1雖然後邊改爲新值了,但是NSArray依然是老值。
在NSArray中,數組本身是淺拷貝。