剛?cè)隝OS這行就是ARC時(shí)代了,有什么我們需要好好注意的呢。
ARC(Automatic Reference Counting) 自動(dòng)引用計(jì)數(shù)
MRC(Manual Reference Counting) 手動(dòng)引用計(jì)數(shù)
歸根到底,都是 引用計(jì)數(shù) 形式的內(nèi)存管理。(不同于java等垃圾回收)

引用計(jì)數(shù)
-(void) method {
NSString *str = @"I am a string";
// your biz code
[str release];
}
一個(gè)堆中的對(duì)象,有一個(gè)指針指向它,引用計(jì)數(shù)?就為1。
?OC方法retain,alloc ,new 都會(huì)使引用計(jì)數(shù)加1
對(duì)應(yīng)的,當(dāng)使用完相應(yīng)的變量要調(diào)用 release 來使引用計(jì)數(shù)減1,當(dāng)調(diào)用調(diào)用release后,如果引用計(jì)數(shù)為0,系統(tǒng)會(huì)釋放相應(yīng)的內(nèi)存。
以上,就是基本的引用計(jì)數(shù)。
MRC 時(shí)代 就是自己要維護(hù) 每一對(duì)的 retain release。
ARC 時(shí)代 永遠(yuǎn)不寫retain,release和autorelease三個(gè)關(guān)鍵字就好。
ARC 時(shí)代:
唯一要做的是用一個(gè)強(qiáng)指針指向這個(gè)對(duì)象,只要指針沒有被置空,對(duì)象就會(huì)一直保持在堆上。當(dāng)將指針指向新值時(shí),原來的對(duì)象會(huì)被release一次。這對(duì)實(shí)例變量,synthesize的變量或者局部變量都是適用的。
那么ARC時(shí)代有沒有可能出現(xiàn)內(nèi)存泄露呢?如果沒有,你要需要注意個(gè)P啊
舉個(gè)有可能出現(xiàn)內(nèi)存泄露的例子
1,循環(huán)參照
A有個(gè)屬性參照B,B有個(gè)屬性參照A,如果都是strong參照的話,兩個(gè)對(duì)象都無法釋放。
這種問題常發(fā)生于把delegate聲明為strong屬性了。
例,
@interface SampleViewController
@property (nonatomic, strong) SampleClass *sampleClass;
@end
@interface SampleClass
@property (nonatomic, strong) SampleViewController *delegate;
@end
把SampleClass 的delegate屬性的strong改為assing即可
以上,描述了下ios 的內(nèi)存管理,引用計(jì)數(shù),下面是在實(shí)際聲明時(shí)會(huì)用到的一些關(guān)鍵詞。
strong
Specifies that there is a strong (owning) relationship to the destination object.
@property (nonatomic,strong) NSString * myString;
@property (nonatomic,strong) NSDate * myDate;
(__strong) NSString *str = @"";
強(qiáng)引用,會(huì)使對(duì)象的引用計(jì)數(shù) +1
在聲明局部變量時(shí),默認(rèn)是strong
weak
Specifies that there is a weak (non-owning) relationship to the destination object.
If the destination object is deallocated, the property value is automatically set to nil.
(Weak properties are not supported on OS X v10.6 and iOS 4; use assign instead.)
@property ( nonatomic, weak) id target;
__weak __typeof__(self) weakSelf = self;
弱引用指針,不會(huì)使對(duì)象引用計(jì)數(shù) +1
assign
Specifies that the setter uses simple assignment. This attribute is the default.
You use this attribute for scalar types such as NSInteger and CGRect.
@property (nonatomic, assign) NSInteger number;
@property (nonatomic, assign) id className;//id必須用assign
用在基礎(chǔ)數(shù)據(jù)類型上,NSInteger,CGRect,struct, id 等。
前面不需要加 “*” 的就用assign吧
copy
Specifies that a copy of the object should be used for assignment.
The previous value is sent a release message.
The copy is made by invoking the copy method. This attribute is valid only for object types, which must implement the NSCopying protocol.
@property (nonatomic, copy) NSString *title;
copy的使用場(chǎng)景為,實(shí)現(xiàn)了NSCopying protocol的類,我想獲取它的值,但是我又不想在原對(duì)象上改變,于是深賦值一份新的值給你,讓你來自由操作。
NSString 類就是這種場(chǎng)景的典型代表。
retain
Specifies that retain should be invoked on the object upon assignment.
The previous value is sent a release message.
@property (nonatomic,strong) NSString * myString;
和strong的用法類似
unsafe_unretained
__unsafe_unretained NSString *string
__unsafe_unretained id value
unsafe_unretained 從名字可以看出,unretained且unsafe,由于是unretained所以與weak有點(diǎn)類似,但是它是unsafe的,什么是unsafe的呢,下面看實(shí)例。
@property (nonatomic, strong) NSString *string1;
@property (nonatomic, unsafe_unretained) NSString *string2;
再來猜一下,下面的代碼會(huì)有什么結(jié)果?
self.string1 = @"String 1";
self.string2 = self.string1;
self.string1 = nil;
NSLog(@"String 2 = %@", self.string2);
程序會(huì)crash掉!!!
其實(shí)就是野指針造成的,所以野指針是可怕的。為何會(huì)造成野指針呢?同于用unsafe_unretained聲明的指針,由于self.string1=nil已將內(nèi)存釋放掉了,但是string2并不知道已被釋放了,所以是野指針。然后訪問野指針的內(nèi)存就造成crash. 所以盡量少用unsafe_unretained關(guān)鍵字。
strong聲明的屬性,
總結(jié):
unretained:類似weak 賦值給某變量,不會(huì)增加引用計(jì)數(shù)
unsafe: 當(dāng)對(duì)象的內(nèi)存釋放后,不會(huì)對(duì)指針設(shè)置為nil,而是繼續(xù)指向該內(nèi)存,導(dǎo)致野指針的存在。
參考文檔:
http://blog.sina.com.cn/s/blog_801997310101a72g.html
http://lizhuang.iteye.com/blog/1989337
http://blog.csdn.net/qq_19697705/article/details/44851073
http://blog.csdn.net/chsadin/article/details/47982923