利用 僵尸环境变量 找出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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值