標(biāo)簽(空格分隔): OCTips
OC的內(nèi)存管理使用了引用計(jì)數(shù)器,一個(gè)對(duì)象中的NSUInteger類型
變量辆布。MRC下向?qū)ο蟀l(fā)送消息retain
使引用計(jì)數(shù)器加1檬贰,release
使引用計(jì)數(shù)器減1庐扫。當(dāng)引用計(jì)數(shù)器為0時(shí),對(duì)象被釋放塑娇。此時(shí)再使用對(duì)象調(diào)用方法就會(huì)導(dǎo)致崩潰澈侠。
MRC內(nèi)存管理原則:誰retain
,誰release
埋酬。
assign
assign
一般用于基本數(shù)據(jù)類型的值哨啃;如果非基本類型使用點(diǎn)語法獲取值會(huì)出現(xiàn)警告Property access result unused - getters should not be used for side effects
,此時(shí)要使用方法調(diào)用[ ]
。其作用域?yàn)閷?duì)象賦值操作的代碼塊區(qū)域写妥,類似于一個(gè)局部變量拳球。
// 運(yùn)行于MRC下
@interface ViewController ()
@property (nonatomic, assign) NSMutableArray *array;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 作用域在viewDidLoad方法中
self.array = [NSMutableArray array];
[self.array addObject:@2];
[self.array addObject:@3];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.array removeObject:@2]; // 程序崩潰,因?yàn)閷?duì)象已被釋放
}
// setter
@property (assign, nonatomic) NSArray *array;
- (void)setArray: (NSArray *)array {
_array = array; // 直接賦值給實(shí)例變量
}
retain strong
持有特性珍特,使一個(gè)對(duì)象的引用計(jì)數(shù)器加一祝峻。retain
是MRC下的,strong
是ARC下的次坡。
// MRC下的方法調(diào)用
@interface ViewController ()
@property (nonatomic, retain) NSMutableArray *array;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.array = [NSMutableArray array]; // 創(chuàng)建時(shí)retainCount +1
[self.array addObject:@2];
[self.array addObject:@3];
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.array removeObject:@2];
// [self.array retain];// 要繼續(xù)使用,就要調(diào)用retain方法保持retainCount大于0画畅。此時(shí)為2
[self.array release]; // retainCount +1, retainCount為0砸琅,釋放對(duì)象
[self.array addObject:@4]; // 再調(diào)用方法,程序崩潰轴踱。
}
// MRC的setter症脂,ARC 系統(tǒng)自動(dòng)完成
@property (strong, nonatomic) NSArray *array;
- (void)setArray: (NSArray *)array {
if (_array != array) {
[_array release]; // 釋放舊值
_array = [array retain];// 將對(duì)象引用計(jì)數(shù)器加一,再賦值給實(shí)例變量
}
}
weak
MRC下淫僻,如果一個(gè)對(duì)象的retainCount
為0诱篷,對(duì)象會(huì)被釋放。但他的引用還保留了被釋放對(duì)象的地址雳灵,形成野指針棕所。此時(shí)調(diào)用方法,編譯不會(huì)報(bào)錯(cuò)悯辙,但運(yùn)行時(shí)會(huì)崩潰琳省。因此MRC下還需要手動(dòng)賦值為nil
。
ARC下躲撰,weak
屬性在retainCount
為0時(shí)针贬,會(huì)自動(dòng)被賦值為nil。減少了形成野指針的風(fēng)險(xiǎn)拢蛋。
ARC下如果想要手動(dòng)釋放對(duì)象桦他,直接將對(duì)象引用賦值為nil即可。
copy
存在一個(gè)對(duì)象和他的副本谆棱,當(dāng)你希望修改其中一個(gè)快压,但對(duì)另一個(gè)對(duì)象不影響時(shí)圆仔,使用copy。作為屬性關(guān)鍵字時(shí)一般用于NSString
和block
嗓节。
相關(guān)點(diǎn):
深拷貝:源對(duì)象引用計(jì)數(shù)不變荧缘,生成一份新的對(duì)象(擁有新的內(nèi)存)
淺拷貝:源對(duì)象引用計(jì)數(shù)加一,生成一份新的引用拦宣,指向源對(duì)象截粗。
值類型
和引用類型
的使用。
注意:如果對(duì)一個(gè)可變類型屬性使用了copy
鸵隧,會(huì)使其變成不可變類型绸罗。此時(shí)調(diào)用可變類型下的方法會(huì)出現(xiàn)崩潰。
@property (nonatomic, copy) NSMutableArray *array;
self.array = [NSMutableArray array];
[self.array addObject:@1]; // 崩潰豆瘫,因?yàn)閟elf.array 運(yùn)行時(shí)是NSArray類型珊蟀,是不能進(jìn)行增刪改操作的。
atomic nonatomic
使用了atomic
的屬性系統(tǒng)會(huì)自動(dòng)增加同步鎖的代碼外驱。這樣在多線程開發(fā)時(shí)育灸,避免多個(gè)線程同時(shí)對(duì)屬性進(jìn)行寫操作,造成無法預(yù)料的屬性值昵宇。但是會(huì)增加性能消耗磅崭,同時(shí)也不能保證絕對(duì)的線程安全。另外瓦哎,屬性默認(rèn)是atomic
的砸喻。
當(dāng)然使用nonatomic
則能節(jié)省性能。
個(gè)人建議就忘掉atomic
吧蒋譬,聲明屬性都使用nonatomic
割岛。多線程安全讀寫的問題,就在需要寫操作時(shí)使用NSLock
犯助、@syncronized
等高級(jí)方式癣漆。