Bram Roelandts
Bram Roelandts

Reputation: 470

Label not being changed properly

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

Answers (1)

Zoltán Matók
Zoltán Matók

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

Related Questions