从全局变量填充textField失败

时间:2019-04-23 22:39:58

标签: swift xcode viewcontroller

我对Swift还是相当陌生,我正在使用使用BLE的Adafruit的Basic Chat iOS应用https://github.com/adafruit/Basic-Chat,并且添加了自己的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()。 在终端输出窗口中,我看到“正在报告电池百分比...”出现,但是在终端输出中没有为batteryVal和batteryField.text为空打印任何值。

由于我正在推送ServoViewController,因此没有安全问题,因此我认为使用全局变量是访问该数据的简便方法。 从我的viewController访问全局变量怎么办?

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

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

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

public var batteryVal: String = ""

收件人:

public var batteryVal: String = "999"

,现在它在textField中打印999。因此,现在的问题似乎是ServoViewController在由BLECentralViewController更新了batteryVal字符串后读取了

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

我现在离开了我的Apple机器,但是当我推第二个ViewController时,也许我可以解决此问题,我可以看看所关注的值是否为空字符串并睡眠一秒钟? 这会睡主线程吗? 如果是这样,我将如何休眠正在执行viewController推送的线程?

3 个答案:

答案 0 :(得分:0)

尝试在reportBatteryPercent中呼叫viewWillAppear。您将得到想要的东西。

这里可能存在一些问题:全局变量在viewDidLoad之前为空,或者只是您的控制器不准备处理此var。

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

答案 1 :(得分:0)

  

由于我要推送ServoViewController,所以没有安全问题,所以我认为使用全局变量是访问该数据的简便方法

不,您仍然可以像下一个vc一样发送值

public  void loadCookie()
{
    Thread myT = new Thread(() =>
    {
        while (true)
        {
            getUserID();
            Thread.Sleep(0);
        }  
    });

    myT.IsBackground = true;
    myT.Start();
}

另外,您不建议使用全局变量,因为它们会造成混淆


let vc = stroybard..... vc.someProperty = // value self.navigationController?.push 是一种异步方法,因此您需要确保在按下时声明为全局的变量具有正确的值

答案 2 :(得分:0)

全局变量是惰性的,因此您不能依赖它们。您应该在结构中或在具有单例引用的类中将变量作为静态变量使用。

有关更多信息,请参见How to create a global variable?