首页 > 解决方案 > 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)
    }



        }

标签: iosswiftmemorybluetoothnotifications

解决方案


尝试在通知中心回调中将自己捕获为无主或弱:

    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


推荐阅读