参考 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:收到一个即时返回一个
[外链图片转存失败(img-9AdQJxEx-1564132185166)(https://img-blog.csdn.net/20160615131737033)]
传入的是空的对象
回调传入了类指针进去,如果不存在就会异常
所以造成了 EXC_BAD_ACCESS异常
###解决办法,就是让 manager1
[外链图片转存失败(img-6vc0gD1S-1564132185167)(https://img-blog.csdn.net/20160615131752158)]
方法1.变成全局变量即可,不让他在主页面消失时候释放
方法2.我用来封装的管理类, 继承自UIView ,这样 界面上始终只存在一个试图控制器,也就不存在释放的问题了;
###这里有个很不错的解释 可以借鉴
http://blog.csdn.net/yi_zz32/article/details/50290373