0

I have a problem in iOS. The green ViewController should turn after a few seconds to red and I have this code:

override func viewDidLoad() {
    super.viewDidLoad()
    let ZeitZahl = arc4random_uniform(1499) + 6000
    usleep(ZeitZahl)
    update()
}

and

func update(){
    self.view.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1.0)
}

The turning to red itself works great! But it doesn't make a delay, it turned directly to red! I have tried it with usleep(5000) instead of usleep(ZeitZahl) but it didn't makes a pause. Please, what does I make wrong?

Blub
  • 121
  • 1
  • 1
  • 6

2 Answers2

2

What you're doing is futile (and wrong). Changes in the interface are ordered in your code but do not happen until the current "transaction" ends, i.e. when your code has finished. Thus, no matter how long you wait, you won't see the change until after your code finishes. For example:

    usleep(bigNumber)
    self.view.backgroundColor = .red
    usleep(bigNumber)
    self.view.backgroundColor = .green

No matter how big bigNumber is, you will never see any red.

However, you should not be using usleep at all. You are blocking the main thread. This freezes the interface, and the Watchdog process will kill your app dead as punishment.

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • What could I do to use it right? – Blub Oct 17 '16 at 21:13
  • I have found a personal way `var GrünZuRot: Timer?`dann `override func viewDidLoad() { super.viewDidLoad() let ZeitZahl = arc4random_uniform(1499) + 6000 self.GrünZuRot = Timer.scheduledTimer(timeInterval: TimeInterval(ZeitZahl/1000), target: self, selector: #selector(update), userInfo: nil, repeats: true) }`und dann `func update(){ self.GrünZuRot = nil self.view.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1.0) } – Blub Oct 17 '16 at 21:19
  • Exactly right. Do you see why? Our code ends, and then the timer calls us back later. We are not blocking. – matt Oct 17 '16 at 21:22
0

You're calling it fine! But 5000 passed to usleep is 5000 microseconds. That's only 0.005 seconds. So you're 1) not sleeping long enough, and 2) it blocks the main thread so you're not going to see the interface update until it finishes anyway. So you'll never see the original value.

Calling usleep won't accomplish this though. It'll block the main thread, so you'll never accomplish what you want.

Dylan Gattey
  • 1,713
  • 13
  • 34
  • Dude, he just asked how to use it. No need to downvote and be obnoxious about it. My answer says it's not the smartest thing to use, but he is calling usleep correctly. – Dylan Gattey Oct 17 '16 at 18:12
  • Yep, you fixed it. No worries. – matt Oct 17 '16 at 18:14
  • Your 2nd paragraph is misleading. Using any form of "sleep" is flat out wrong and can't be used to do what the OP wants. And a good answer would explain why `usleep` can't be used and offer solutions to achieve the desired result. – rmaddy Oct 17 '16 at 18:18
  • How could I do it right? @Dylan Gattey – Blub Oct 17 '16 at 21:12
  • I have found a personal way `var GrünZuRot: Timer?`dann `override func viewDidLoad() { super.viewDidLoad() let ZeitZahl = arc4random_uniform(1499) + 6000 self.GrünZuRot = Timer.scheduledTimer(timeInterval: TimeInterval(ZeitZahl/1000), target: self, selector: #selector(update), userInfo: nil, repeats: true) }`und dann `func update(){ self.GrünZuRot = nil self.view.backgroundColor = UIColor(red: 1, green: 0, blue: 0, alpha: 1.0) } – Blub Oct 17 '16 at 21:20