Swift Notification Center导致内存泄漏

时间:2019-08-06 15:51:14

标签: ios swift memory bluetooth notifications

第一次张贴。我对Swift和编码以及一般性语言很陌生,遇到了我似乎无法解决的问题。

在我的代码中,我有两个视图控制器。第一视图控制器允许用户查看蓝牙设备,并选择要连接的设备。当用户选择设备时,它会选择第二个视图控制器,后者显示来自蓝牙设备的温度数据。

这一切都很好,但如果我先回到第一个视图控制器,然后再次选择相同的设备,我现在会从该设备收到两个相同的温度读数。 (蓝牙设备从我的代码中接收到两个相同的命令,并向后发送两个值)。

基本上,每次我在视图控制器之间来回搜索时,似乎都会创建视图控制器的另一个实例,从而造成内存泄漏。 (如果我前后来回反复进行了五次搜索,那么每次单击按钮以获取一个值时,我都会收到五个蓝牙读数)

我相信我的问题出在我创建和解雇Notification Center Observers上,但是我似乎无法找出正确的解决方案。

我遗漏了与我的问题无关的代码,所以如果我缺少解决问题所需的任何代码,请告诉我。任何帮助将不胜感激!

//第一视图控制器

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!"
            }
        }

// Second View Controller

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)
    }



        }

1 个答案:

答案 0 :(得分:0)

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

    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