标签未正确更改
Label not being changed properly
在我的应用程序中,我正在接收 UDP 命令。当收到某个 UDP 命令时,应该更改标签,但这并没有发生。这是我的代码:
func listenForStatusChange() {
self.firstServerRun = true
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
while 1 == 1 {
if self.packetReceived == true || self.firstServerRun == true {
self.firstServerRun = false
self.packetReceived = false
let server:UDPServer=UDPServer(addr:"192.168.1.9",port: 8888)
let run:Bool=true
while run{
let (data, _,_)=server.recv(1024)
if let d=data{
if let str=String(bytes: d, encoding: NSUTF8StringEncoding){
self.packetReceived = true
if str == "Online" {
dispatch_async(dispatch_get_main_queue()) {
print("it is online")
self.statusLabel.text = "Online"
self.switchOnline = true
}
}
if str == "1" {
self.lampValue = 1
self.state = str
}
if str == "0" {
self.lampValue = 0
self.state = str
}
// self.changeSwitchValue()
}
}
server.close()
break
}
} else {
}
}
})
}
此函数是从 ViewDidLoad 调用的。如果 str == "online",self.statusLabel.text 应该等于 "Online"。当 viewController 加载时,就是这种情况。但是当我回到另一个 ViewController 并回到这个时,它不再起作用了。该函数仍然被调用(因为 "it is online" 仍然被打印)但是标签不再显示..
有什么帮助吗?非常感谢!
我有一个疯狂的猜测。
根据您的代码猜测,视图控制器可能正在订阅其他某个对象或信号作为观察者。
当您从视图中弹出它时,您期望 VC 到 deinit
。但我不认为会发生这种情况,因为你在无限循环中对 self 有很强的引用。
当您第二次显示 VC 时,此 VC 的前一个实例仍在内存中,但不再可见。我猜新实例无法订阅为观察者或其他东西,但您仍然看到来自此 VC.
的先前内存实例的日志消息
当您登录并输入 viewDidLoad()
时,尝试记录 self ( print(self)
)。
在第二次展示这个VC之后,如果两个登录的自己的内存地址不匹配,我想我是对的。
解决方案可能是在闭包的捕获列表中包含一个 weak self,这样您就没有对它的强引用,如下所示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { [weak self] () -> Void in
if let weakSelf = self {
while 1 == 1 {
}
}
})
注意[弱自]在闭包体前面
或者你知道...不要使用无限循环
在我的应用程序中,我正在接收 UDP 命令。当收到某个 UDP 命令时,应该更改标签,但这并没有发生。这是我的代码:
func listenForStatusChange() {
self.firstServerRun = true
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { () -> Void in
while 1 == 1 {
if self.packetReceived == true || self.firstServerRun == true {
self.firstServerRun = false
self.packetReceived = false
let server:UDPServer=UDPServer(addr:"192.168.1.9",port: 8888)
let run:Bool=true
while run{
let (data, _,_)=server.recv(1024)
if let d=data{
if let str=String(bytes: d, encoding: NSUTF8StringEncoding){
self.packetReceived = true
if str == "Online" {
dispatch_async(dispatch_get_main_queue()) {
print("it is online")
self.statusLabel.text = "Online"
self.switchOnline = true
}
}
if str == "1" {
self.lampValue = 1
self.state = str
}
if str == "0" {
self.lampValue = 0
self.state = str
}
// self.changeSwitchValue()
}
}
server.close()
break
}
} else {
}
}
})
}
此函数是从 ViewDidLoad 调用的。如果 str == "online",self.statusLabel.text 应该等于 "Online"。当 viewController 加载时,就是这种情况。但是当我回到另一个 ViewController 并回到这个时,它不再起作用了。该函数仍然被调用(因为 "it is online" 仍然被打印)但是标签不再显示..
有什么帮助吗?非常感谢!
我有一个疯狂的猜测。
根据您的代码猜测,视图控制器可能正在订阅其他某个对象或信号作为观察者。
当您从视图中弹出它时,您期望 VC 到 deinit
。但我不认为会发生这种情况,因为你在无限循环中对 self 有很强的引用。
当您第二次显示 VC 时,此 VC 的前一个实例仍在内存中,但不再可见。我猜新实例无法订阅为观察者或其他东西,但您仍然看到来自此 VC.
的先前内存实例的日志消息当您登录并输入 viewDidLoad()
时,尝试记录 self ( print(self)
)。
在第二次展示这个VC之后,如果两个登录的自己的内存地址不匹配,我想我是对的。
解决方案可能是在闭包的捕获列表中包含一个 weak self,这样您就没有对它的强引用,如下所示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { [weak self] () -> Void in
if let weakSelf = self {
while 1 == 1 {
}
}
})
注意[弱自]在闭包体前面
或者你知道...不要使用无限循环