I am trying to exit from for loop according to condition but I ran into the issue as it does not exit even from the loop. Here is a loop of my code.
var isFailure = true
let dispatchGroup = DispatchGroup()
var myFailureTask: Int?
for item in 1...5 {
dispatchGroup.enter()
test(item: item, completion: {
print("Success\(item)")
dispatchGroup.leave()
}, failureBlock: {
print("Failure\(item)")
myFailureTask = item
dispatchGroup.leave()
return
})
dispatchGroup.wait()
}
dispatchGroup.notify(queue: .main) {
if let myFailure = myFailureTask {
print("task failure \(myFailure)")
} else {
print("all task done")
}
}
func test(item: Int,completion: @escaping(() -> ()), failureBlock: @escaping(() -> ())) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure = !isFailure
if isFailure {
failureBlock()
} else {
completion()
}
}
The return
returns from current scope.
In this case it's returning from the failureBlock: {}
and NOT from the for loop scope.
You have to refactor the code to achieve what you are trying to do.
EITHER (in case this code is executing synchronously) you can return a success
value true
| false
from the function by making function
's return type Bool
and removing the failureBlock
argument.
OR (in case this code is executing asynchronously) you have to think of waiting on one task to complete/fail before triggering the other.
UPDATE
I think following might be a simplified version of this code -
var isFailure: Bool = false
func callTest(for item: Int) {
print("task initiated \(item)")
test(item: item, completion: {
print("task succeeded \(item)")
if item < 5 {
callTest(for: item+1)
} else {
print("all tasks done")
}
}, failureBlock: {
print("task failed \(item)")
})
}
func test(item: Int, completion: @escaping (() -> Void), failureBlock: @escaping (() -> Void)) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure.toggle()
if isFailure {
failureBlock()
} else {
completion()
}
}
callTest(for: 1)
var isFailure = false
let dispatchGroup = DispatchGroup()
var myFailureTask: Int?
for item in 1...5 {
dispatchGroup.enter()
test(item: item, completion: {
print("Success\(item)")
dispatchGroup.leave()
}, failureBlock: {
print("Failure\(item)")
myFailureTask = item
dispatchGroup.leave()
})
if isFailure == true {
break
}
dispatchGroup.wait()
}
dispatchGroup.notify(queue: .main) {
if let myFailure = myFailureTask {
print("task failure \(myFailure)")
} else {
print("all task done")
}
}
func test(item: Int,completion: @escaping(() -> ()), failureBlock: @escaping(() -> ())) {
Thread.sleep(forTimeInterval: TimeInterval(item))
isFailure = !isFailure
if isFailure {
failureBlock()
} else {
completion()
}
}```
Made few changes work like a charm.
Any one has better idea please comment
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.