简体   繁体   中英

iOS 11 CoreBluetooth: Cannot remove an observer CBPeripheral for the key path “delegate”

Ever since iOS 11 was released, I'm experiencing an esporadic but frequent crash with the following signature:

Cannot remove an observer <CBPeripheral 0x1c010ef10> for the key path "delegate" from <CBPeripheral 0x1c010ef10> because it is not registered as an observer.

This happens in the context of a scan for Bluetooth devices, a later connection to one of them and a final cleanup of the whole process. All these tasks are performed in a non-main dispatch queue to soften the pressure on the main thread (for smoother UI experience). This very code has been running without incident ever since iOS 9 days and only now that iOS 11 came out, started to crash.

The only references I've found in the net so far regarding this behaviour are this and this post for the Estimote SDK . These references suggest that something might be going on with parallel instances of the CBCentralManager in different dispatch queues, however, nothing regarding special care on the matter is stated in the official Programming Guide . Also, a response from an Apple Staff member to another CoreBluetooth issue stating:

iOS 11 is in general going to be less forgiving for apps which don't hold a proper reference to CB objects...

Doesn't sound very encouraging. I tried profiling the app and looking for potential leaks using XCode and it's companion tools but this didnt't shed much light on it either.

Has anybody else experienced similar issues? Any suggestions on how to workaround it? Ideas on where to dig next?

After some testing period, in our particular case the solution consisted in translating all the Bluetooth stack related work to the mainQueue . Meaning that all the related callbacks exists within Main-thread territory.

This solution requires extra caution with the work performed in those callbacks (UI runs here too), but since most CoreBluetooth actions are asynchronous by default, this has proven feasible. This workaround has been confirmed in iOS 11 and so far no issues have been reported in iOS 12 as well.

The takeaway here is: Handle ONLY the absolutely necessary bits in mainQueue , and then transfer the rest of the load elsewhere if necessary.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM