Bhavuk Jain Bhavuk Jain - 1 month ago 7
Swift Question

Remove reference of a closure when it's still undergoing a certain task in Swift

I've created a closure, and the value is returned after some time. During this period I'm again calling this closure with different data. The problem is, the closure response is received but the previous closure response is also received. How can I remove the reference to the first closure so I can get the response from the latest closure only?

Here's my code:

func getUsers() {

self.getUsers = GetUsers()

self.getUsers.getUsersData(latitude: Double(latitude)!, longitude: Double(longitude)!, range:range)
{ (usersArray, error) in

}

}


UPDATE:

I've passed the current object from the closure and it seems to work fine. Here's the updated code:

func getUsers() {

self.getUsers = GetUsers()

self.getUsers.getUsersData(latitude: Double(latitude)!, longitude: Double(longitude)!, range:range)
{[weak self] (usersArray, error, getUsersObject) in

if let strongSelf = self {
if strongSelf.getUsers != getUsersObject {
return
}
}
}

}


If the returned object from the closure doesn't match the reinitialized object, I just return it.

Answer

That would depend upon the implementation of getUsersData. In general there is probably no way to cancel the callback. The best you can do is to have the callback code check some sort of flag or identifier when it runs, and do nothing if the check fails.

Example:

    ids.append("do this one")
    delay(2) { [weak self] in
        let id = "do this one"
        if let s = self, s.ids.contains(id) {
            print(id)
        }
    }
    ids.append("don't do this one")
    delay(2) { [weak self] in
        let id = "don't do this one"
        if let s = self, s.ids.contains(id) {
            print(id)
        }
    }
    ids.remove(at:1) // cancel this one

Prints "I will do this one", but does not print "don't do this one". It would have, but we cancelled it by removing it from the ids array.

Comments