CBCentralManager 和自动引用计数
CBCentralManager and Automatic Reference Counting
我有两个应用程序,它们的 BLE 功能非常相似,但是一个可以正确扫描并发现外围设备,而另一个则不能。
他们都报告初始化指向 CBCentralManager
的指针没有问题并检查它是否打开并正常工作,但一个继续发现并能够连接到设备,而另一个则没有。
在不起作用的那个中,对 scanForPeripheralsWithServices
的调用顺利结束,但从未触发 didDiscoverPeripheral
回调。我能想到的最大区别是,一个项目使用纯 Objective-C
和 ARC,而另一个项目混合使用 Objective-C
和 C++,并且不使用自动引用计数。
这可能是问题的根源吗?如果是这样,有没有办法解决它?我过去可以在没有 ARC 的情况下使用 CoreBluetooth
,但如果我无法从文档中解析它,它可能已经改变了。
如果不是 ARC,则对 scanForPeripheralsWithServices 的两次调用如下所示:
功能性
- (int) findBLEPeripherals:(int) timeout
{
NSLog(@"start finding");
if (self.CM.state != CBCentralManagerStatePoweredOn)
{
NSLog(@"CoreBluetooth not correctly initialized !");
NSLog(@"State = %d (%s)\r\n", self.CM.state, [self centralManagerStateToString:self.CM.state]);
return -1;
}
[NSTimer scheduledTimerWithTimeInterval:(float)timeout target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO];
[self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@RBL_SERVICE_UUID]] options:nil];
NSLog(@"scanForPeripheralsWithServices");
return 0; // Started scanning OK !
}
无法正常工作
- (void)startScan
{
NSLog(@"startScan");
isScanning = true;
NSDictionary *options = nil;
didUpdateDiscoveredDeviceFlag = [delegate respondsToSelector:@selector(didUpdateDiscoveredRFduino:)];
if (didUpdateDiscoveredDeviceFlag) {
options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
}
[devices removeAllObjects];
if (self.central.state != CBCentralManagerStatePoweredOn)
{
NSLog(@"CoreBluetooth not correctly initialized !");
// NSLog(@"State = %d (%s)\r\n", self.central.state, [self centralManagerStateToString:self.central.state]);
}
[NSTimer scheduledTimerWithTimeInterval:(float)60 target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO];
[self.central scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@RBL_SERVICE_UUID]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
if (didUpdateDiscoveredDeviceFlag) {
[self startRangeTimer];
}
}
以及两个头文件的相关部分:
功能性
@interface BLE : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate> {
}
@property (nonatomic,assign) id <BLEDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *peripherals;
@property (strong, nonatomic) NSMutableArray *peripheralsRssi;
@property (strong, nonatomic) CBCentralManager *CM;
@property (strong, nonatomic) CBPeripheral *activePeripheral;
无法正常工作
@interface BLEDeviceManager : NSObject <CBCentralManagerDelegate>
{
}
+ (BLEDeviceManager *)sharedDeviceManager;
@property (strong, nonatomic) CBCentralManager *central;
非常感谢任何建议!
所以这有点傻,但是重新启动 phone + clean/build 修复了所有问题。我怀疑这两个应用程序在释放 CBCentralManager 句柄时彼此配合得不好,但这只是一种猜测。老实说,我对 CoreBluetooth 或 Objective C 不是很熟悉,所以我的猜测并不是那么充分。
我有两个应用程序,它们的 BLE 功能非常相似,但是一个可以正确扫描并发现外围设备,而另一个则不能。
他们都报告初始化指向 CBCentralManager
的指针没有问题并检查它是否打开并正常工作,但一个继续发现并能够连接到设备,而另一个则没有。
在不起作用的那个中,对 scanForPeripheralsWithServices
的调用顺利结束,但从未触发 didDiscoverPeripheral
回调。我能想到的最大区别是,一个项目使用纯 Objective-C
和 ARC,而另一个项目混合使用 Objective-C
和 C++,并且不使用自动引用计数。
这可能是问题的根源吗?如果是这样,有没有办法解决它?我过去可以在没有 ARC 的情况下使用 CoreBluetooth
,但如果我无法从文档中解析它,它可能已经改变了。
如果不是 ARC,则对 scanForPeripheralsWithServices 的两次调用如下所示:
功能性
- (int) findBLEPeripherals:(int) timeout
{
NSLog(@"start finding");
if (self.CM.state != CBCentralManagerStatePoweredOn)
{
NSLog(@"CoreBluetooth not correctly initialized !");
NSLog(@"State = %d (%s)\r\n", self.CM.state, [self centralManagerStateToString:self.CM.state]);
return -1;
}
[NSTimer scheduledTimerWithTimeInterval:(float)timeout target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO];
[self.CM scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@RBL_SERVICE_UUID]] options:nil];
NSLog(@"scanForPeripheralsWithServices");
return 0; // Started scanning OK !
}
无法正常工作
- (void)startScan
{
NSLog(@"startScan");
isScanning = true;
NSDictionary *options = nil;
didUpdateDiscoveredDeviceFlag = [delegate respondsToSelector:@selector(didUpdateDiscoveredRFduino:)];
if (didUpdateDiscoveredDeviceFlag) {
options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES]
forKey:CBCentralManagerScanOptionAllowDuplicatesKey];
}
[devices removeAllObjects];
if (self.central.state != CBCentralManagerStatePoweredOn)
{
NSLog(@"CoreBluetooth not correctly initialized !");
// NSLog(@"State = %d (%s)\r\n", self.central.state, [self centralManagerStateToString:self.central.state]);
}
[NSTimer scheduledTimerWithTimeInterval:(float)60 target:self selector:@selector(scanTimer:) userInfo:nil repeats:NO];
[self.central scanForPeripheralsWithServices:[NSArray arrayWithObject:[CBUUID UUIDWithString:@RBL_SERVICE_UUID]] options:@{ CBCentralManagerScanOptionAllowDuplicatesKey : @YES }];
if (didUpdateDiscoveredDeviceFlag) {
[self startRangeTimer];
}
}
以及两个头文件的相关部分:
功能性
@interface BLE : NSObject <CBCentralManagerDelegate, CBPeripheralDelegate> {
}
@property (nonatomic,assign) id <BLEDelegate> delegate;
@property (strong, nonatomic) NSMutableArray *peripherals;
@property (strong, nonatomic) NSMutableArray *peripheralsRssi;
@property (strong, nonatomic) CBCentralManager *CM;
@property (strong, nonatomic) CBPeripheral *activePeripheral;
无法正常工作
@interface BLEDeviceManager : NSObject <CBCentralManagerDelegate>
{
}
+ (BLEDeviceManager *)sharedDeviceManager;
@property (strong, nonatomic) CBCentralManager *central;
非常感谢任何建议!
所以这有点傻,但是重新启动 phone + clean/build 修复了所有问题。我怀疑这两个应用程序在释放 CBCentralManager 句柄时彼此配合得不好,但这只是一种猜测。老实说,我对 CoreBluetooth 或 Objective C 不是很熟悉,所以我的猜测并不是那么充分。