diff --git a/device/bluetooth/bluetooth_l2cap_channel_mac.mm b/device/bluetooth/bluetooth_l2cap_channel_mac.mm index 1792d66a3f4cc..3e849efd9db6b 100644 --- a/device/bluetooth/bluetooth_l2cap_channel_mac.mm +++ b/device/bluetooth/bluetooth_l2cap_channel_mac.mm @@ -76,6 +76,14 @@ } - (void)l2capChannelClosed:(IOBluetoothL2CAPChannel*)l2capChannel { + // IOBluetooth holds this delegate unsafe_unretained (FB13705522) and ARC + // does not retain `self`. `_channel->OnChannelClosed()` below drops the C++ + // owner's strong ref to this object; if `_strongSelf` was never armed + // (failed/pending open), that is the last ref and `self` is freed + // mid-method. Pin `self` for the duration of this method. + BluetoothL2capChannelDelegate* __strong strongSelf = self; + (void)strongSelf; + [_l2capChannel setDelegate:nil]; // If `_channel` still exists, notify it that the channel was closed so it diff --git a/device/bluetooth/bluetooth_rfcomm_channel_mac.mm b/device/bluetooth/bluetooth_rfcomm_channel_mac.mm index a2411754cf4d0..d353ddc78e14e 100644 --- a/device/bluetooth/bluetooth_rfcomm_channel_mac.mm +++ b/device/bluetooth/bluetooth_rfcomm_channel_mac.mm @@ -76,6 +76,14 @@ } - (void)rfcommChannelClosed:(IOBluetoothRFCOMMChannel*)rfcommChannel { + // IOBluetooth holds this delegate unsafe_unretained (FB13705522) and ARC + // does not retain `self`. `_channel->OnChannelClosed()` below drops the C++ + // owner's strong ref to this object; if `_strongSelf` was never armed + // (failed/pending open), that is the last ref and `self` is freed + // mid-method. Pin `self` for the duration of this method. + BluetoothRfcommChannelDelegate* __strong strongSelf = self; + (void)strongSelf; + [_rfcommChannel setDelegate:nil]; // If `_channel` still exists, notify it that the channel was closed so it