Reputation: 470
In my app, I'm receiving UDP commands. When a certain UDP command is received, a label should be changed but this doesn't happen. This is my code:
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 {
}
}
})
}
This function is called from the ViewDidLoad. If str == "online", self.statusLabel.text should be equal to "Online". When the viewController loads, this is the case. But when I segue back to another ViewController and back to this one, it doesn't work anymore. The function is still called (because "it is online" is still printed) but the label isn't shown anymore..
Any help? Thank you very much!
Upvotes: 0
Views: 39
Reputation: 4045
I have a wild guess.
Guessing from your code, the view controller might be subscribing to some other object or signal as an observer.
You are expecting the VC to deinit
when you pop it from view. But I don't think that happens, because you have a strong reference to self in an infinite loop.
When you present the VC a second time, the previous instance of this VC is still in memory, but is not visible anymore. I'm guessing the new instance is unable to subscribe as the observer or something, but you are still seeing the log messages from the previous in-memory instance of this VC.
Try logging self ( print(self)
) when you are logging AND in viewDidLoad()
.
After presenting this VC the second time, if the memory addresses of the two logged selves don't match up, I guess I'm right.
The solution might be to include a weak self in the capture list of your closure, so you don't have a strong reference to it, like so:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), { [weak self] () -> Void in
if let weakSelf = self {
while 1 == 1 {
}
}
})
Notice [weak self] in front of the closure body.
Or you know... don't use an infinite loop
Upvotes: 1