调度队列异步调用
Posted
技术标签:
【中文标题】调度队列异步调用【英文标题】:Dispatch Queue Async Call 【发布时间】:2019-07-11 23:55:06 【问题描述】:我在另一个网络请求中的 for 循环中触发了一个网络请求。我正在使用核心数据,但我相当确定这不是核心数据问题,而是异步问题。
Firebase 请求中的 2 个打印语句正确打印数据,但没有 DispatchQueue,数组返回为空(在网络请求完成之前)。
这是崩溃的图片:
这是代码本身:
var userReps = [UserRepresentation]()
// Fetch all Friends -> update Core Data accordingly
func fetchFriendsFromServer(completion: @escaping (Error?) -> Void = _ in)
let backgroundContext = CoreDataStack.shared.container.newBackgroundContext()
// 1. Fetch all friends from Firebase
FirebaseDatabase.UserDatabaseReference.child(CoreUserController.shared.userPhoneNumber).child(UserKeys.UserFriends).child(UserKeys.UserAcceptedFriends).observe(.value) (data) in
if let dictionary = data.value as? [String: String]
var userReps = [UserRepresentation]()
let group = DispatchGroup()
group.enter()
for friend in dictionary
let friendName = friend.value
let friendId = friend.key
FirebaseDatabase.UserDatabaseReference.child(friendId).observe(.value, with: (data) in
if let dictionary = data.value as? [String: Any]
guard let gender = dictionary[UserKeys.UserGender] as? String else return
guard let bio = dictionary[UserKeys.UserBio] as? String else return
guard let status = dictionary[UserKeys.UserStatus] as? String else return
guard let avatarUrl = dictionary[UserKeys.UserAvatarUrlKey] as? String else return
let friendRepresentation = UserRepresentation(avatarUrl: avatarUrl, name: friendName, number: friendId, gender: gender, status: status, bio: bio)
userReps.append(friendRepresentation)
print("HERE, friends fetched: ", friendRepresentation)
print("HERE, reps fetched: ", userReps)
group.leave()
)
group.notify(queue: .main)
// 2. Update Core Data value with Firebase values
self.updateFriends(with: userReps, in: backgroundContext)
// 3. Save Core Data background context
do
try CoreDataStack.shared.save(context: backgroundContext)
catch let error
print("HERE. Error saving changes to core data: \(error.localizedDescription)")
任何帮助都会大有帮助
【问题讨论】:
【参考方案1】:自从
let group = DispatchGroup()
是一个局部变量,你在这里使用观察
FirebaseDatabase.UserDatabaseReference.child(friendId).observe(.value, with: (data) in
它会在函数释放后重新调用它,要么使其成为实例变量,要么使其成为单个观察者
FirebaseDatabase.UserDatabaseReference.child(friendId).observeSingleEvent(of:.value) (data) in
在 for 循环中也输入 enter
for friend in dictionary
group.enter()
【讨论】:
要花很长时间才能注意到导致问题的观察。非常感谢以上是关于调度队列异步调用的主要内容,如果未能解决你的问题,请参考以下文章