for example, I have a variable X = 0 , I have to call the getStatus() method that sends a request to the server and updates the variable Y , and while X == Y I re-send a request to the server every 2 seconds for 10 seconds, if for example during some of their requests, came Y = 1 , that is, Y != X - I stop the cycle and stop sending requests, if after 10 seconds they are still equal, I will show an alert.

I tried to do this, but the method is not suitable, since the cycle is processed instantly, and the methods in memory are invoked on a timer, but they remember the old one, not updated by one of the Y requests:

 func valueInspection() { var time = 2 for _ in 1...10 { if x == y { time += 2 _ = Timer.scheduledTimer(timeInterval: TimeInterval(time), target: self, selector: #selector(General.getStatus), userInfo: nil, repeats: false) } else { print ("VALUE CHANCHED") } } } 
  • in getStatus() if do not match, stop the timer? - VAndrJ
  • @VAndrJ in getStatus() when retrieving data, the value of perperty Y changes. By clicking on the button, I send a request to the server to change the variable Y , call valueChange() , and call the valueChange() state checking method, change it or not, about which the actual question is pbogdanv

3 answers 3

 var x: Int = 1 var y: Int = 1 var startTimestamp: TimeInterval = 0 private let timeout: TimeInterval = 10 func valueInspection() { startTimestamp = NSTimeIntervalSince1970 delayedInspection(delay: 0) } private func delayedInspection(delay: UInt64) { guard startTimestamp > NSTimeIntervalSince1970 - timeout * 1000 else { return } DispatchQueue.global().asyncAfter(deadline: .now() + timeout) { if x == y { delayedInspection(delay: 2) // send request } else { print("value changed") } } } 
  • does not enter let dispatchTime: DispatchTime = DispatchTime.now () + Double (Int64 (delay * NSEC_PER_SEC)) / Double (NSEC_PER_SEC) DispatchQueue.main.asyncAfter (deadline: dispatchTime, execute: {if self.currentguard == self.guardCar {self.delayedInspection (delay: 2) // send request} else {print ("value changed")}}} ` - pbogdanv
  • does not enter `let dispatchTime: DispatchTime = DispatchTime.now () + Double (Int64 (delay * NSEC_PER_SEC)) / Double (NSEC_PER_SEC) DispatchQueue.main.asyncAfter (deadline: dispatchTime, execute: {if self.currentguard == self. guardCar {self.delayedInspection (delay: 2) // send request} else {print ("value changed")}}) ` - pbogdanv
  • @pbogdanv Fixed, checked in the playground, everything seems to be ok - Threat70

why don't you use a loop

repeat { statements } while condition

eg

 var time = 2 repeat { time += 2 _ = Timer.scheduledTimer(timeInterval: TimeInterval(time), target: self, selector: #selector(General.getStatus), userInfo: nil, repeats: false) if time == 10 { break } } while x != y 
  • The fact is that the loop constructions are processed instantly, that is, all timer requests are immediately placed in the queue, depending on the current Y, but not from the current one at the beginning of the cycle, but from the received one: the first request is sent -> if Y = 0 through 2 seconds sent again, if Y = 0, then repeat, if Y = 1 stop the process, well, if 10 seconds have passed and everything is unchanged (Y = 0), then also stop with the message - pbogdanv
 func valueInspection() { if timer == nil { timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(vc.getStatus), userInfo: nil, repeats: true) } } func getStatus() { ... if timer != nil { counterTimer += 1 if x != y { timer.invalidate() timer = nil counterTimer = 0 } else { if counterTimer == 5 { timer.invalidate() timer = nil counterTimer = 0 present(UIAlertController.addAllert("Oops..", message: "Try Again"), animated: true, completion: nil) } } }