从全局变量填充textField失败

问题描述 投票:0回答:3

我是Swift的新手,我正在使用Adafruit的基本聊天iOS应用程序https://github.com/adafruit/Basic-Chat,它使用BLE,我正在添加自己的viewController并推送它而不是Adafruit提供的那个。我的ViewController(ServoViewController)按预期显示。

我正在通过BLE与Arduino进行通信,并从Arduino接收数据,并正在解析BLECentralViewController文件中的相关部分(并打印到终端)数据。

我在BLECentralViewController类之外设置了一个String变量(因此根据我的理解它应该是全局的)。我将数据读入BLECentralViewController中的变量并再次成功打印。

然后我尝试使用该String变量来填充viewController中的textField,但是textField永远不会被写入。

在BLECentralViewController文件中,我有在类之外声明的变量,如下所示:

var dataReceived: String = ""
public var batteryVal: String = "" // global variable

我检查来自Arduino的传入数据。如果它包含字符串“Battery”,我知道它是电池数据。我可以接收并获取子串(电池%)并将其打印到终端。

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
                print("Value Received: \((characteristicASCIIValue as String))")
                dataReceived = (characteristicASCIIValue as String)

                if dataReceived.contains("Battery:")    {
                    print ("Battery value: ", dataReceived)
                    print("Substring: ", dataReceived.substring(from: 8))
                    batteryVal = dataReceived.substring(from: 8)
                    print("Printing batteryVal: ", batteryVal)

                }
                NotificationCenter.default.post(name:NSNotification.Name(rawValue: "Notify"), object: nil)
                cvcrd.reportValvePosition()

            }
        }
    }

在我的viewController(ServoViewController)中,我有以下功能

func reportBatteryPercent() {
        // print battery value here
        batteryField.text = batteryVal
        print("Reporting Battery Percentage here...", batteryVal)
    }

首先,我想在ServoViewController首次加载时填充textField,所以我在viewDidLoad()中调用了reportBatteryPercent()。在终端输出窗口中,我看到“报告电池百分比在这里......”,但是电池电压的终端输出中没有打印值,而且batteryField.text为空。

由于我正在推动我的ServoViewController没有segue,所以我认为全局变量将是访问该数据的简单方法。从viewController访问全局变量我做错了什么?

编辑:根据建议我已将reportBatteryPercent()放在viewWillAppear中,如下所示:

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        reportBatteryPercent()
    }

但是,在ServoViewController中仍然无法打印数据。我尝试从以下位置更改String的声明:

public var batteryVal: String = ""

至:

public var batteryVal: String = "999"

现在它在textField中打印999。所以问题现在似乎是ServoViewController在BLECentralViewController更新后读取batteryVal字符串

编辑2:我已经确认上面我回到第一个viewController(BLECentralViewController),然后返回第二个viewController(ServoViewController)。现在显示正确的值。

我现在远离我的Apple机器,但也许我可以通过推送第二个ViewController来解决这个问题,我可以看到感兴趣的值是否为空字符串并且睡眠一秒钟?这会睡到主线吗?如果是这样,我将如何睡眠正在推动viewController的线程?

swift xcode viewcontroller
3个回答
0
投票

试着在reportBatteryPercent打电话给viewWillAppear。你会得到你想要的东西。

这可能是一些问题:全局变量在viewDidLoad之前是空的,或者只是你的控制器没有准备好处理这个变量。

要检查它,请将全局变量的起始值设置为非空字符串。


0
投票

由于我正在推动我的ServoViewController没有segue,所以我认为一个全局变量将是一种访问该数据的简单方法

不,你仍然可以向下一个vc发送价值

let vc = stroybard.....
vc.someProperty = // value
self.navigationController?.push

再加上你不鼓励使用全球变量,因为它们令人困惑


qazxsw poi是一种异步方法,你需要确保当你推送时声明为全局的变量具有正确的值


0
投票

全局变量是懒惰的,所以你不能依赖它们。您应该将变量作为结构中的静态变量或具有单例引用的类中的静态变量。

有关更多信息,请参阅didUpdateValueFor

© www.soinside.com 2019 - 2024. All rights reserved.