ios - centralManagerDidUpdateState throws unrecognized selector sent to instance error -


i have view controller starts bluetooth scan when push button.

here .h file:

#import <uikit/uikit.h> @import corebluetooth;  @interface viewcontrollerintropage2 : uiviewcontroller{     iboutlet uibutton *scanforfetchtagsbutton; }  @property (nonatomic, retain) uibutton *scanforfetchtagsbutton; @property (nonatomic, retain) cbcentralmanager *mcentralmanager;  -(ibaction)scanbuttonpressed:(id)sender;   @end 

here .m file:

#import "viewcontrollerintropage2.h" #import "bluetoothlemanager.h"  @interface viewcontrollerintropage2 ()  @end  @implementation viewcontrollerintropage2  @synthesize scanforfetchtagsbutton;   - (id)initwithnibname:(nsstring *)nibnameornil bundle:(nsbundle *)nibbundleornil {     self = [super initwithnibname:nibnameornil bundle:nibbundleornil];     if (self) {         // custom initialization     }     return self; }  - (void)viewdidload {     [super viewdidload];     // additional setup after loading view. }  - (void)didreceivememorywarning {     [super didreceivememorywarning];     // dispose of resources can recreated. }  -(ibaction)scanbuttonpressed:(id)sender {     nslog(@"scan button clicked");      self.mcentralmanager = [[bluetoothlemanager alloc]initializecbcentralmanager];      nslog(@"scan done");  } /* #pragma mark - navigation  // in storyboard-based application, want little preparation before navigation - (void)prepareforsegue:(uistoryboardsegue *)segue sender:(id)sender {     // new view controller using [segue destinationviewcontroller].     // pass selected object new view controller. } */  @end 

here bluetoothlemanager files:

.h file:

#import <foundation/foundation.h>  @import corebluetooth; @import quartzcore;  @interface bluetoothlemanager : nsobject < cbcentralmanagerdelegate, cbperipheraldelegate>  @property (strong, retain) cbcentralmanager *mbtcentralmanager;  -(cbcentralmanager*) initializecbcentralmanager;   @end 

.m file:

#import "bluetoothlemanager.h" #import "constants.h"  @implementation bluetoothlemanager   -(cbcentralmanager*)initializecbcentralmanager{     nslog(@"initializing cbcentral manager");     return self.mbtcentralmanager = [[cbcentralmanager alloc] initwithdelegate:self queue:nil]; }  #pragma mark - cbcentralmanagerdelegate  // method called whenever have connected ble peripheral - (void)centralmanager:(cbcentralmanager *)central didconnectperipheral:(cbperipheral *)peripheral { }  // cbcentralmanagerdelegate - called cbperipheral class main input parameter. contains of information there know ble peripheral. - (void)centralmanager:(cbcentralmanager *)central diddiscoverperipheral:(cbperipheral *)peripheral advertisementdata:(nsdictionary *)advertisementdata rssi:(nsnumber *)rssi {     nslog(@"discovered %@ @ %@", peripheral.name, rssi);  }  -(void)centralmanagerdidupdatestate:(cbcentralmanager *)central{     nslog(@"start scan");      if(central.state == cbcentralmanagerstatepoweredon){         nslog(@"scanning btle device");          [central scanforperipheralswithservices:@[[cbuuid uuidwithstring:device_name]] options:@{ cbcentralmanagerscanoptionallowduplicateskey : @yes }];     } } @end 

the issue app keeps crashing/pausing. throw unrecognized selector sent instance error, doesn't happen. i've checked make sure there isn't issue button, because when remove self.mcentralmanager = [[bluetoothlemanager alloc]initializecbcentralmanager]; app doesn't crash.

can tell why crash happening , how can fix it?

your code has multiple problems. right not keeping reference instance of bluetoothlemanager, means deallocated shortly after return scanbuttonpressed:, instance still delegate of cbcentralmanager, depending on how cbcentralmanager stores delegate might lead crash or won't call delegate methods. delegate not retained, if instance gets released cbcmanager either access invalid memory or has set delegate nil.

instead of keeping reference cbcentralmanager in viewcontroller should keep reference instance of bluetoothlemanager. solve first problem, if keep instance around won't deallocated , cbcentralmanagerdelegate methods called correctly.

and using wrong allocation pattern. in objective-c if call alloc have call complete deal, e.g. [[class alloc] init] or [[class alloc] initwithsomething:something]. methods start init have return own class.

those problems can spot now.

i have fixed , modernized code:

btmgr.h

#import <foundation/foundation.h>  @import corebluetooth;  @interface bluetoothlemanager : nsobject <cbcentralmanagerdelegate, cbperipheraldelegate> @property (strong, readonly) cbcentralmanager *mbtcentralmanager; @end 

btmgr.m

#import "bluetoothlemanager.h" //#import "constants.h"  @implementation bluetoothlemanager  - (instancetype)init {     self = [super init];     nslog(@"initializing bluetoothlemanager");     _mbtcentralmanager = [[cbcentralmanager alloc] initwithdelegate:self queue:nil];     return self; }  #pragma mark - cbcentralmanagerdelegate  // method called whenever have connected ble peripheral - (void)centralmanager:(cbcentralmanager *)central didconnectperipheral:(cbperipheral *)peripheral { }  // cbcentralmanagerdelegate - called cbperipheral class main input parameter. contains of information there know ble peripheral. - (void)centralmanager:(cbcentralmanager *)central diddiscoverperipheral:(cbperipheral *)peripheral advertisementdata:(nsdictionary *)advertisementdata rssi:(nsnumber *)rssi {     nslog(@"discovered %@ @ %@", peripheral.name, rssi); }  -(void)centralmanagerdidupdatestate:(cbcentralmanager *)central{     nslog(@"start scan");      if(central.state == cbcentralmanagerstatepoweredon){         nslog(@"scanning btle device"); //        [central scanforperipheralswithservices:@[[cbuuid uuidwithstring:device_name]] options:@{ cbcentralmanagerscanoptionallowduplicateskey : @yes }];     } } @end 

vc.h

#import <uikit/uikit.h>  @interface viewcontrollerintropage2 : uiviewcontroller @property (nonatomic, strong) uibutton *scanforfetchtagsbutton;  -(ibaction)scanbuttonpressed:(id)sender;  @end 

vc.m

#import "viewcontrollerintropage2.h" #import "bluetoothlemanager.h"  @interface viewcontrollerintropage2 () @property (strong) bluetoothlemanager *bluetoothmanager; @end  @implementation viewcontrollerintropage2  -(ibaction)scanbuttonpressed:(id)sender {     nslog(@"scan button clicked");     if (!self.bluetoothmanager) {         // create if doesn't exist         self.bluetoothmanager = [[bluetoothlemanager alloc] init];     }     nslog(@"scan done"); }  @end 

Comments

Popular posts from this blog

python - mat is not a numerical tuple : openCV error -

c# - MSAA finds controls UI Automation doesn't -

wordpress - .htaccess: RewriteRule: bad flag delimiters -