如果有錯誤的地方,請指正。
首先這裏涉及到iOS的內存管理機制,大致來講就是有申請就必定要有釋放,在mrc狀態下,如果使用alloc init等創建對象,其對象內部的引用計數器就會加1,你就必須要進行一次release,然後系統會在dealloc中自動釋放。
assign--基礎數據類型,簡單賦值,引用計數器不變化。
retain--引用計數器加1,一般用於NSString和基礎數據類型以外的類對象創建,他的含義是淺拷貝,也就是拷貝對象指針,但不拷貝內部內容,指針所指內容是一致的。
copy--引用計數器加1,一般用於nsstring,指深拷貝,也就是拷貝對象的內容和指針,消除舊對象。
strong--arc機制下的強指針引用,引用計數器加1,他的含義約等於retain。
weak-arc機制下的弱指針,所有指向這個對象的weak指針都將被置爲nil,能避免因爲意外釋放而導致的carsh。
@interface AController : UIViewController
{
__weak UIView *aView;
}
@end
@implementation AController
- (void) viewDidLoad
{
[super viewDidLoad];
UIView *view = [[UIView alloc]initWithFrame:CGRectZero];
[self.view addSubview:view];
aView = view;
}
@end
基本還用weak聲明,因爲Controller並不直接“擁有”控件,控件由它的父view“擁有”。使用weak關鍵字可以不增加控件引用計數,確保控件與父view有相同的生命週期。
控件在被addSubview後,相當於控件引用計數+1;父view銷燬後,所有的子view引用計數-1,則可以確保父view銷燬時子view立即銷燬。weak的控件在removeFromSuperview後也會立即銷燬,而strong的控件不會,因爲Controller還保有控件強引用。
在控件addSubview後再對weak變量賦值,防止控件被立即釋放。
@property (retain,nonatomic) NSString *rStr;
@property (copy, nonatomic) NSString *cStr;
- (void)test:
{
NSMutableString *mStr = [NSMutableStringstringWithFormat:@"abc"];
self.rStr = mStr;
self.cStr = mStr;
NSLog(@"mStr:%p,%p", mStr,&mStr);
NSLog(@"retainStr:%p,%p", _rStr, &_rStr);
NSLog(@"copyStr:%p,%p", _cStr, &_cStr);
}
假如,mStr對象的地址爲0x11,也就是0x11是@“abc”的首地址,mStr變量自身在內存中的地址爲0x123;
當把mStr賦值給retain的rStr時,rStr對象的地址爲0x11,rStr變量自身在內存中的地址爲0x124;rStr與mStr指向同樣的地址,他們指向的是同一個對象@“abc”,這個對象的地址爲0x11,所以他們的值是一樣的。
當把mStr賦值給copy的cStr時,cStr對象的地址爲0x22,cStr變量自身在內存中的地址0x125;cStr與mStr指向的地址是不一樣的,他們指向的是不同的對象,所以copy是深複製,一個新的對象,這個對象的地址爲0x22,值爲@“abc”。
如果現在改變mStr的值:
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", _rStr);
NSLog(@"copyStr:%@", _cStr);
結果,
使用retain的字串rStr的值:@"abcde",
而使用copy的字串cStr的值:@"abc",
所以,如果一般情況下,我們都不希望字串的值跟着mStr變化,所以我們一般用copy來設置string的屬性。
如果希望字串的值跟着賦值的字串的值變化,可以使用strong,retain。
注意:上面的情況是針對於當把NSMutableString賦值給NSString的時候,纔會有不同,如果是賦值是NSString對象,那麼使用copy還是strong,結果都是一樣的,因爲NSString對象根本就不能改變自身的值,他是不可變的。
所以總的來說,NSString本身是無所謂的,但是如果一個 NSString 指針指向了一個 NSMutableString的內存空間的話,如果使用 strong 修飾的話,如果你在別處修改這個值的話,那麼原來的值也會改變。用 copy 是生成了一份新的內存空間,原值不會改變,所以一般使用copy就足夠了,因爲我們很少有需求能跟隨字符串變化而變化的字符串。