在使用Instrumnents對程序進行內(nèi)存測試的時候,發(fā)現(xiàn)有幾處異常處理的地方提示內(nèi)存泄露。經(jīng)過分析得知,因為異常處理,改變代碼執(zhí)行路徑,導(dǎo)致編譯生成的 release 代碼沒有執(zhí)行。
簡單寫了些測試代碼驗證:
- (void)viewDidLoad {
[super viewDidLoad];
@try {
NSMutableArray *stringList = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++) {
[stringList addObject: @"string instance."];
}
[self throwException];
}
@catch (NSException *exception) {
NSLog(@"catch Exception : %@", exception);
}
@finally {
}
}
- (void)throwException
{
[NSException raise:@"An Exception." format:@"Exception Description."];
}
反復(fù)進出這個頁面幾次后,在Instruments上果然看到提示內(nèi)存泄露,而且泄露的地方就指明是 @try{ } 里面創(chuàng)建的對象。

解決思路
1, 盡量不要在@try{}里面有操作,導(dǎo)致對象的引用引用計數(shù)增加。@try{ } 語句塊里面只有有可能拋出異常的語句。
修改后的代碼:
- (void)viewDidLoad {
[super viewDidLoad];
NSMutableArray *stringList = [[NSMutableArray alloc] init];
for (int i = 0; i < 100; i++) {
[stringList addObject: @"string instance."];
}
@try {
[self throwException];
}
@catch (NSException *exception) {
NSLog(@"catch Exception : %@", exception);
}
@finally {
}
}
最后用Instruments檢查一下,一切正常了。
2, 查看了蘋果的開發(fā)文檔,發(fā)現(xiàn)有這么一段描述:
By default in Objective C, ARC is not exception-safe for normal releases:
It does not end the lifetime of __strong variables when their scopes are abnormally terminated by an exception.
It does not perform releases which would occur at the end of a full-expression if that full-expression throws an exception.
A program may be compiled with the option -fobjc-arc-exceptions in order to enable these, or with the option -fno-objc-arc-exceptions to explicitly disable them, with the last such argument “winning”.