iOS 蓝牙检索外设导致 EXC_BAD_ACCESS 崩溃

Posted

技术标签:

【中文标题】iOS 蓝牙检索外设导致 EXC_BAD_ACCESS 崩溃【英文标题】:iOS Bluetooth retrievePeripherals causes EXC_BAD_ACCESS crash 【发布时间】:2013-09-06 21:43:10 【问题描述】:

我需要定期重新连接到外围设备,但尝试重新连接会崩溃。

首先,我的中心扫描外围设备的 UUID,然后连接,然后将外围设备.UUID 存储到 CFUUIDRef 变量中,然后断开连接。接下来,要重新连接,它会从变量中检索 UUID,然后在执行 retreivePeripherals 或稍后执行后续的 didRetrievePeripherals 时以“EXC_BAD_ACCESS”崩溃。

也许我没有正确存储 UUID,但我没有看到错误。谢谢。

这是代码............

-(void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral

    ///////////////////////   C E N T R A L   C O N N E C T E D   P E R I P H E R A L   //////////////////////

    [self.centralManager   stopScan];
    // Make sure we get the discovery callbacks
    peripheral.delegate = pwr_tx_management;

    switch( PWR_TX_manager.present_operation )
    
        case POLLING_FOR_GENERIC_DVINEWAVE_DEVICE:
            if( dbg_ev )        printf("1");        
            // Add new record for connection device to local system status database:
            update_device_record( &packed_ad_record    );       //      ==>  device_record_index
            // Store peripheral UUID for later, perioed re-connection for polling:
            area_device_status[ device_area ][ device_record_index ].peripheral_UUID = peripheral.UUID;
                                 // uses declaration:  CFUUIDRef            peripheral_UUID;

    // Disconnect:        !!!
        [self.centralManager   cancelPeripheralConnection:   peripheral];
        break;


        case OPERATION_SPECIFIC_POLLING:
                                        NSLog( @"(7) didConnectPeripheral   " );
            if( dbg_ev )        printf("2");        
            // Proceed with reading device's status and updating local database:
                [peripheral   discoverServices:nil];    // request service, characteristics, then request device send its packed status record

            break;
        default:
            break;
        






// Connects to device specificed by index next_dbase_record .
void connect_specific_device( void )

                                                        NSLog( @"(5) connect_specific_device    - next_dbase_record = %d", next_dbase_record );
    CFUUIDRef uuid = area_device_status[ device_area ][ next_dbase_record ].peripheral_UUID;

    if( uuid )
    
        // Request call to didRetrievePeripherals() with CBPeripheral:
        [pwr_tx_management.centralManager retrievePeripherals:[NSArray arrayWithObject: (id)CFBridgingRelease(uuid)]];     <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< crashes here with:  Thread 1: EXC_BAD_ACCESS
    
    else
    
        NSLog( @"   - missing area_device_status[][].peripheral_UUID ");
    





// Iniates connection to peripheral device specified before by retrievePeripherals.
- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(CBPeripheral *)peripheral

    NSLog( @"(6) didRetrievePeripherals");
    [central   connectPeripheral:peripheral   options:nil];

【问题讨论】:

【参考方案1】:

解决方案是存储 ASCII UUID,并使用retrieveConnectedPeripherals 和retreivePeripherals。存储指针可能失败,因为没有保留数据。我还实现了 tdevoy 的解决方案。 didRetrievePeripherals 被调用,但其外围设备列表为空,因此我添加了retrieveConnectedPeripherals 和 didRetrieveConnectedPeripherals,它们被调用,并列出了我成功连接到的外围设备。 (Apple Prog. 指南含糊不清,缺少示例代码。)

【讨论】:

所以我不太明白你在说什么。 retrieveConnectedPeriphs 只抓取您已经连接到的外围设备。那是你想做的吗?【参考方案2】:

让我先说我是在车上用手机写的,所以请原谅我的格式很差。生病只是指出我看到的主要问题。您没有采用正确的委托方法:

它是:

- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(NSArray *) peripherals

不是这个:

- (void) centralManager:(CBCentralManager *)central didRetrievePeripherals:(CBPeripheral *)peripheral

我也不明白你为什么要这么做cfbridgingrelease。只需将其作为@[(id)yourCfuuidref] 传递即可。你没有创建那个 cfuuid。

【讨论】:

我从 Apples temp_sensor 示例中复制了 didRetrievePeripherals:(CBPeripheral *)peripheral。但是,Apple 的健康温度计和心率监测器使用 NSArray 格式。 我认为问题在于我如何存储 UUID。我担心我正在存储一个指针,它会以某种方式发生变化,并且应该存储 ASCII UUID。 您要做的是:将您的 UUID 的 NSString 版本存储到 NSUserDefaults 中。当您再次需要它时,检索 UUID 字符串并使用 CFUUIDCreateFromString 创建您的 CFUUIDRef。然后将该 CFUUIDRef 传递给retrievePeripherals

以上是关于iOS 蓝牙检索外设导致 EXC_BAD_ACCESS 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

iOS 连接蓝牙2.0的外设怎么实现

ios设备app作为蓝牙外设端

iOS蓝牙接收外设数据自动中断

iOS设置蓝牙外设播放音频

iOS CoreBluetooth 获取唯一的外设 ID

蓝牙外设卡在 iOS 上的“正在连接”状态