ios - Swift Notification Center 导致内存泄漏
问题描述
第一次海报。我对 Swift 和编码和一般知识非常陌生,并且遇到了我似乎无法解决的问题。
在我的代码中,我有两个视图控制器。第一个视图控制器允许用户查看蓝牙设备,并选择要连接的设备。当用户选择一个设备时,它会转到第二个视图控制器,该控制器会显示来自蓝牙设备的温度数据。
这一切都很好,很漂亮,但是如果我回到第一个视图控制器,然后再次选择相同的设备,我现在会从设备收到两个相同的温度读数。(蓝牙设备从我的代码中接收到两个相同的命令,并返回两个值)。
基本上每次我在视图控制器之间来回切换时,似乎都会创建视图控制器的另一个实例,从而造成内存泄漏。(如果我来回切换五次,每次单击按钮接收一个值,我都会收到五个蓝牙读数)
我相信我的问题在于我创建和解雇通知中心观察员,但我似乎无法找出正确的解决方案。
我遗漏了我觉得与我的问题无关的代码,所以如果我遗漏了解决问题所需的任何代码,请告诉我。任何帮助将不胜感激!
// 第一个视图控制器
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("*****************************")
print("Connection complete")
print("Peripheral info: \(String(describing: blePeripheral))")
//Stop Scan- We don't need to scan once we've connected to a peripheral. We got what we came for.
centralManager?.stopScan()
print("Scan Stopped")
//Erase data that we might have
data.length = 0
//Discovery callback
peripheral.delegate = self
//Only look for services that matches transmit uuid
peripheral.discoverServices(nil)
performSegue(withIdentifier: "Go", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destination = segue.destination as! TempPage
destination.peripheral = blePeripheral
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if characteristic == rxCharacteristic {
if let ASCIIstring = NSString(data: characteristic.value!, encoding: String.Encoding.utf8.rawValue) {
characteristicASCIIValue = ASCIIstring
NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Notify"), object: nil)
connectionStatus = "Connected!"
}
}
// 第二个视图控制器
override func viewDidLoad() {
super.viewDidLoad()
//Create and start the peripheral manager
peripheralManager = CBPeripheralManager(delegate: self, queue: nil)
//-Notification for updating the text view with incoming text
updateIncomingData()
}
override func viewDidDisappear(_ animated: Bool) {
peripheralManager?.stopAdvertising()
self.peripheralManager = nil
super.viewDidDisappear(animated)
NotificationCenter.default.removeObserver(self)
}
func updateIncomingData () {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "Notify"), object: nil , queue: nil){
notification in
if characteristicASCIIValue != nil
{
self.rawValue = characteristicASCIIValue as String
print(characteristicASCIIValue)
}
self.batteryLevelLabel.text = ("\(String(batteryLevel))%")
}
@IBAction func returnToFirstViewController(_ sender: Any) {
navigationController?.popViewController(animated: true)
dismiss(animated: true, completion: nil)
}
}
解决方案
尝试在通知中心回调中将自己捕获为无主或弱:
func updateIncomingData () {
NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "Notify"), object: nil , queue: nil) { [unowned self] notification in
if characteristicASCIIValue != nil
{
self.rawValue = characteristicASCIIValue as String
print(characteristicASCIIValue)
}
self.batteryLevelLabel.text = ("\(String(batteryLevel))%")
}
这篇文章可能有用:https ://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
推荐阅读
- javascript - JS 在 Dropbox 上使用 SQL 选择
- c# - 当 SQL 返回浮点数时,ExecuteScalar 返回双精度
- c# - 为什么 .NET 框架开发人员在展开循环时选择 10(在 x64 12 上)作为因素?
- javascript - 涉及数组和 json javascript 的基本 2d 游戏问题
- matlab - 如何使用ode45在matlab中求解耦合微分方程
- c++ - `~uintptr_t(value)` 方法体是什么意思?C++
- sql - 选择两个(计算的)日期值中的较大者
- php - 为什么 PHP isset 和 Null 合并运算符使用连接运算符抛出通知?
- ionic3 - 如何使用 pickContact() 显示选定的联系人 - ionic-v3
- c# - .NET Core 模型绑定问题