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 一般都是由于向已經銷毀的對象發送資訊時 給出的錯誤)
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX90zdNFTWU5kMFRUT4FEVkZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jNwQDOykTM0EzMxYDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
那麼 遇到這種情況?我們如何來調試程式呢?
這就要使用到 僵屍環境變量了 --- 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