閱讀927 返回首頁    go 阿裏雲 go 技術社區[雲棲]


iOS開發那些事-性能優化–查找和解決僵屍對象

內存泄漏是當一個對象或變量在使用完成後沒有釋放掉,那麼如果我們走了另外一個極端情況會什麼樣呢?這就導致過渡釋放(over release)問題,從而使對象“僵屍化”,對象稱為僵屍(zombies)對象。一個對象已經被釋放過了,或者調用者沒有這個對象的所有權而釋放它,都會造成過渡釋放,產生僵屍對象。

僵屍對象或許對很多人聽起來很恐怖、也很陌生,如果要說起EXEC_BAD_ACCESS異常,可能大家並不陌生。試圖調用僵屍對象方法應用會崩潰(應用直接跳出),並拋出異常EXEC_BAD_ACCESS。

我們看看代碼ViewController的代碼片段:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

NSUInteger row = [indexPath row];

NSDictionary *rowDict = [self.listTeams objectAtIndex:row];

NSString *rowValue  =  [rowDict objectForKey:@"name"];

NSString *message = [[NSString alloc] initWithFormat:@”您選擇了%@隊。”, rowValue];

UIAlertView *alert = [[UIAlertView alloc]initWithTitle:@”請選擇球隊”

message:message

delegate:self

cancelButtonTitle:@”Ok”

otherButtonTitles:nil];

    [alert release];                                                                                                                                          ①

[message release];

    [alert show];                                                                                                                                             ②

[tableView deselectRowAtIndexPath:indexPath animated:YES];

}


注意看程序代碼的黑體部分,你會發現什麼問題嗎?程序運行的結果拋出EXEC_BAD_ACCESS異常。假設我們現在無法找到問題,可以使用Instruments工具的Zombies跟蹤模板。其中Instruments選擇Zombies模板,點擊Profile按鈕就可以進入了。

14

點擊Allocations的“i”按鈕,彈出Target菜單配置Zombies模板,在Launch Configuration中勾選Record reference counts和Enable NSZombie detection。其中Record reference counts是顯示引用計數,Enable NSZombie detection是能夠檢測僵屍對象。

22
這樣在程序運行的時候,如果發現僵屍對象它就會彈出一個對話框,點擊其中“→”按鈕,在屏幕的下方會顯示僵屍對象的詳細信息。

31

僵屍對象為UIAlertView類型,從上到下僵屍對象是引用計數的變化是:創建 → 釋放 → 僵屍化。打開擴展詳細視圖,在右邊的跟蹤堆棧信息進入我們程序代碼,會打開對應代碼,定位僵屍對象。

51

在上麵的3條高亮顯示的代碼會影響對象引用計數,從中我們不難發現問題。關於解決方案就本例而言需要將代碼②行的顯示警告框的[alert show]語句,放在[alert release]語句之前調用就可以了。這就是僵屍對象問題。


最後更新:2017-04-04 07:03:44

  上一篇:go HDU 2642 二維樹狀數組
  下一篇:go ubuntu 安裝軟件時,提示:由於沒有公鑰,無法驗證下列簽名