Ваш код более / менее правильный.Вот упрощение, которое работает на игровой площадке, где вы можете увидеть, как работает ваша логика.Как указывает @vadian, вы не «добавляете» к dict, вместо этого вы присваиваете значение свойству, но, как указывает vdmzz, вы должны и могли бы делать это с Set
.
* 1003.*
Печать:
["HDSFG2323BGYDSG53"]
["HDSFG2323BGYDSG53", "JDSFG2323BPTDSG59"]
["HDSFG2323BGYDSG53", "ODSFG2323BABDSG50", "JDSFG2323BPTDSG59"]
Но я очень подозреваю, что причина, по которой ваш код все еще не работает, заключается в асинхронной природе retrieveUsersInfo
.Вы просматриваете весь Set
в его пустом состоянии и заполняете его значением пользователя после того, как получено.Вот демонстрация того, что, как мне кажется, происходит:
import UIKit
import PlaygroundSupport
struct User {
var uid: String
}
func retrieveUsersInfo(uid: String, completion: @escaping (User) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
let user = User(uid: uid)
completion(user)
}
}
var processedUsers: Set<String> = Set()
var uids = ["HDSFG2323BGYDSG53", "JDSFG2323BPTDSG59", "ODSFG2323BABDSG50"]
uids.forEach({
if !processedUsers.contains($0) {
retrieveUsersInfo(uid: $0, completion: { (user) in
processedUsers.insert(user.uid)
print("Callback returned", processedUsers)
})
print("Loop ended", processedUsers)
}
})
PlaygroundPage.current.needsIndefiniteExecution = true
Вывод:
Loop ended []
Loop ended []
Loop ended []
Callback returned ["HDSFG2323BGYDSG53"]
Callback returned ["HDSFG2323BGYDSG53", "JDSFG2323BPTDSG59"]
Callback returned ["HDSFG2323BGYDSG53", "JDSFG2323BPTDSG59", "ODSFG2323BABDSG50"]
Итак, ваш Set всегда будет пустым в конце цикла, потому что асинхронная задача не имеетт вернулся.Это может быть хорошо, если вы ведете постоянную запись (NSUserDefaults, CoreData) обработанных вами uid, но если это эфемерно - то есть исчезнет, когда приложение закроется, вы захотите улучшить свой журнал обработкис чем-то вроде «состояния» (но есть дюжина различных способов решить его, но это не так).
Вот пример, который реализует Hashable
состояние:
import UIKit
import PlaygroundSupport
struct User {
var uid: String
var state: ProcessedState
init(uid: String) {
self.uid = uid
self.state = .none
}
enum ProcessedState {
case none
case started
case success
case error
}
}
extension User: Equatable {
static func == (lhs: User, rhs: User) -> Bool {
return lhs.uid == rhs.uid
}
}
extension User: Hashable {
var hashValue: Int {
return uid.hashValue
}
}
func retrieveUsersInfo(user: User, completion: @escaping (User) -> Void) {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
var user = user
user.state = .success // or .error
completion(user)
}
}
var processedUsers: Set<User> = Set()
var users: [User] = [
User(uid: "HDSFG2323BGYDSG53"),
User(uid: "JDSFG2323BPTDSG59"),
User(uid: "ODSFG2323BABDSG50")]
users.forEach({ user in
if processedUsers.first(where: { $0 == user })?.state != .success {
var user = user
user.state = .started
processedUsers.insert(user)
retrieveUsersInfo(user: user, completion: { (user) in
print("Callback returned", processedUsers)
})
print("Loop ended", processedUsers)
}
})
PlaygroundPage.current.needsIndefiniteExecution = true