利用 殭屍環境變量 找出Crash原因( 殭屍斷點 )

     iOS程序Crash,如果由於程序上的的邏輯錯誤或者數組越界,一般都會有錯誤日誌會輸出錯誤的原因,已經跟蹤堆棧錯誤信息。但是 有的時候,就會沒有任何錯誤日誌輸出。程序直接crash掉。有多種原因造成這種沒有 錯誤日誌輸出的情況。大致可以有 :1: 使用了斷言(注意不是斷點)。2:_objc_sendMessage not found Object ( 某一對象被提前釋放 )。

下面給一個例子(爲了造成對象提前被釋放,使用mrc手動管理內存比較易於實現demo),程序crash 但是沒有任何的錯誤日誌輸出。

BtnView 類

#import <UIKit/UIKit.h>

@interface BtnView : UIView

-(void)test;

@end

#import "BtnView.h"

@implementation BtnView

-(instancetype)initWithFrame:(CGRect)frame
{
    if(self=[super initWithFrame:frame]){
        
       
        
    }
    return self;
}



-(void)test
{
    NSLog(@"_objc_sendMessage not found Object");
}


@end

ViewController


#import "ViewController.h"
#import "BtnView.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    BtnView *btnView=[[BtnView alloc] initWithFrame:CGRectMake(10, 50, self.view.bounds.size.width-20, 40)];
    [self.view addSubview:btnView];
    [btnView release];
    [btnView release];
    
    UIButton *btn=[UIButton buttonWithType:UIButtonTypeSystem];
    [btn setTitle:@"對象被釋放,測試殭屍環境變量" forState:UIControlStateNormal];
    btn.frame=CGRectMake(10, 50, self.view.bounds.size.width-20, 40);
    [btn addTarget:btnView action:@selector(test) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    [btn release];
    
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


程序bulid 成功,允許,點擊按鍵:程序 崩潰,但沒有任何錯誤日誌輸出,只提示EXC_BAD_ACCESS:(當然如果你是一名老手,一眼就能看出EXC_BAD_ACCESS 一般都是由於向已經銷燬的對象發送信息時 給出的錯誤)




那麼 遇到這種情況?我們如何來調試程序呢?

這就要使用到 殭屍環境變量了 --- NSZombieEnabled

至於NSZombieEnabled,就是當設置NSZombieEnabled環境變量後,一個對象銷燬時會被轉化爲_NSZombie,該對象只會被標記爲“釋放”但卻仍然被保留在內存當中。如此一來,當我們訪問某個殭屍對象時,Xcode會提醒我們該對象雖然能夠被訪問、但在實際環境中已經不應存在。在這種模式下,我們將能夠瞭解到正常情況下無法獲得的實時狀態與對象位置。設置NSZombieEnabled後,當你向一個已經釋放的對象發送消息,這個對象就不會向之前那樣Crash或者產生 一個難以理解的行爲,而是放出一個錯誤消息,然後以一種可預測的可以產生debug斷點的方式消失(原文是die),因此我們就可以找到具體或者大概是哪 個對象被錯誤的釋放了。

如何在xcode中配置 殭屍環境 變量呢?

Product -> Scheme -> Edit Scheme -> Environment Variables -> 添加一個殭屍環境變量:NSZombieEnabled  值設爲 Yes 同時保證環境變量被使用(也就是前面的 勾 要選上)


1:


2:

3:


4:



殭屍環境 變量配置完成後,這時候,我們再允許程序,點擊按鍵,就會有錯誤日誌 跟蹤堆棧的信息輸出:




最後在附上一篇其他排除bug的文章:http://mobile.51cto.com/iphone-377138.htm



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章