Arti Arti - 1 month ago 15
Swift Question

Exit from infinite loop if it peforms operation too long

I have a function that send command and then in infinite loop read data in from

USB
device with completion callback:

func dump(success: (() -> Void)? = nil, failure: (()->Void)? = nil) {
HIDDevice.sharedInstance.sendCommad(command: "dump")
while true {
for data in HIDDevice.sharedInstance.readBuf {
if data == "dumpcomplete":
success?()
return
}
}
}


And i need to check if this while loop works
> 1
second and didn't get success, then call
failure
closure and stop loop.

I tried to use this before loop, but it didn't help. Thread blocks by loop.

func setTimeout(delay:TimeInterval, block:@escaping ()->Void) -> Timer {
return Timer.scheduledTimer(timeInterval: delay, target: BlockOperation(block: block), selector: #selector(Operation.main), userInfo: nil, repeats: false)
}

let handle = setTimeout(1, block: { () -> Void in
failure()?
return
})

Answer

While I don't think such "busy loops" are a good idea, I don't know anything about HIDDevice so I can't offer an alternative to such a loop. So this answer only addresses the direct question of how to exit the while loop after 1 second.

One possible solution is to calculate a time interval and check that each time:

func dump(success: (() -> Void)? = nil, failure: (()->Void)? = nil) {
    HIDDevice.sharedInstance.sendCommad(command: "dump")
    let deadline = Date.timeIntervalSinceReferenceDate + 1 // add one second from now
    while Date.timeIntervalSinceReferenceDate < deadline {
        for data in HIDDevice.sharedInstance.readBuf {
            if data == "dumpcomplete":
               success?()
               return
        }
    }
}

This calculates a time interval in the future and checks the current time against that future value. Once that time has passed the while loop will exit.

Comments