我对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推送的线程?
答案 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?。