EXC_BAD_ACCESS异常 _block_invoke 问题

来源:互联网 发布:网络宣传方法 编辑:程序博客网 时间:2024/06/03 09:33

EXC_BAD_ACCESS异常 _block_invoke 问题

参考 http://blog.csdn.net/dqjyong/article/details/22511643 这个帖子

贴下报错图

这里写图片描述

代码背景

在接入JHL蓝牙的过程中,我使用一个ViewController类 来作为这个蓝牙的管理类 (父类是视图控制器ViewController)
当我在主界面OrderViewController中

   JHLBTPosVManager *manager1 = [[JHLBTPosVManager alloc] init];    [self.view addSubview:manager1.view];

执行以上代码

贴出JHLBTPosVManager.m的具体代码

////  JHLBTPosVManager.m//  BluetoothTest////  Created by Aotu on 16/6/7.//  Copyright © 2016年 szjhl. All rights reserved.//#import "JHLBTPosVManager.h"#import "JhlblueController.h"@interface JHLBTPosVManager ()<JhlblueControllerDelegate>{    NSMutableArray *deviceList;   //查询到的设备名称列表    NSMutableArray *connectedList;  //连接成功的列表}@end@implementation JHLBTPosVManager- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view.    deviceList = [[NSMutableArray alloc] init];    connectedList = [[NSMutableArray alloc] init];    //设置回调与初始化蓝牙    [[JhlblueController sharedInstance]  setDelegate:self];    [[JhlblueController sharedInstance]  InitBlue];    [[JhlblueController sharedInstance]  SetEncryMode:0x01 :0x01 :0x01];  //设置加密方式    //1.查找设备    if ([[JhlblueController sharedInstance] isBTConnected])  //判断是否连接状态    {        dispatch_async(dispatch_get_main_queue(), ^{            if ([[JhlblueController sharedInstance] isBTConnected]){                //1.1 先判断是否需要 断开连接 = YES                [[JhlblueController sharedInstance] disconnectBT];            }else{                NSLog(@"未连接设备,无需断开...");            }        });    }else        //2.否则,连接蓝牙    {        [[JhlblueController sharedInstance] scanBTDevice:5 nScanType:0x00];  //0 是列表返回  1:收到一个即时返回一个    }}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}#pragma mark ===============蓝牙部分的回调===============//0x01 发现新的蓝牙  //搜索模式为一个个返回时回调(多次)- (void)onFindNewPeripheral:(CBPeripheral *)newPeripheral{    NSLog(@"%s,findNewBt:%@",__func__,newPeripheral.name);}//0x01 搜索到的蓝牙设备  //搜索模式为列表返回时回调- (void)onDeviceFound:(NSArray *)DeviceList{    NSLog(@"DeviceList === %@",DeviceList);    NSString *bdm = [[NSUserDefaults standardUserDefaults] objectForKey:@"uuidName"];    CBPeripheral *dataPath= nil;    if ([DeviceList count] ==0)  //    {    }}/* 判断是否处于连接状态  -1 连接后断开i  00 未找到设备  01 连接成功 02 正在连接  03 连接失败 *///连接状态反馈-(void)onBlueState:(int)nState{    if (nState ==BLUE_SCAN_NODEVICE)    {    }    else if (nState ==BLUE_CONNECT_FAIL){    }    else if (nState ==BLUE_CONNECT_SUCESS)    {    }    else if (nState ==BLUE_CONNECT_ING){    }    else if (nState ==BLUE_POWER_STATE_ON){   //当手机蓝牙开启时检测回调    }    else if (nState ==BLUE_POWER_STATE_OFF){  //当手机蓝牙关闭时检测回调        if ([[JhlblueController sharedInstance] isBTConnected]){            [[JhlblueController sharedInstance] disconnectBT];        }    }}@end

就出现上图中的错误,后来联系jhl的工作人员,才帮我找到了问题所在

问题原因

由于我使用的是ViewController来封装,因此初始化方法均放置在了ViewDidload方法中去实现,由于在主界面调用了 JHLBTPosVManager 且 只是定义了一个局部变量

 JHLBTPosVManager *manager1 = [[JHLBTPosVManager alloc] init];

这就造成了 当我主页面函数走完,就释放掉了我的管理类对象 manager1
换句话说:
主界面viewController加载完毕,紧接着加载了 manager1 的viewController,此时主界面的 viewController就被释放掉了,
因为我释放了主页面Viewcontroller 所以导致类manager1就不存在了
这时候我想回调

  [[JhlblueController sharedInstance] scanBTDevice:5 nScanType:0x00];  //0 是列表返回  1:收到一个即时返回一个

这里写图片描述
传入的是空的对象
回调传入了类指针进去,如果不存在就会异常
所以造成了 EXC_BAD_ACCESS异常

解决办法,就是让 manager1

这里写图片描述
方法1.变成全局变量即可,不让他在主页面消失时候释放

方法2.我用来封装的管理类, 继承自UIView ,这样 界面上始终只存在一个试图控制器,也就不存在释放的问题了;


这里有个很不错的解释 可以借鉴

http://blog.csdn.net/yi_zz32/article/details/50290373

0 0