什么时候 .removeObserver ?
When to .removeObserver ?
该应用应仅加载本地发布的帖子。
使用 GeoFire 在 FB 中有一个分支“posts_location
”。
我想先填充“nearbyPostsKeys
”数组,然后从 FB 的分支帖子中加载那些引用 REF_POSTS.
的特定帖子
在 viewDidLoad
中,我调用了一个具有完成处理程序(来自 FB 的数据)的函数。
这是采用完成处理程序的 func 声明:
func populateNearbyAndPassIt(completion:@escaping ([String])->()) {
let theGeoFire = GeoFire(firebaseRef: DB_BASE.child("posts_location"))
let location = CLLocation(latitude: Location.sharedInstance.currentLatitude, longitude: Location.sharedInstance.currentLongitude)
let circleQuery = theGeoFire!.query(at: location, withRadius: 6.0)
let newRefHandle: FIRDatabaseHandle = circleQuery!.observe(.keyEntered, with: { (key, location) in
self.nearbyPostsKeys.append(key!)
completion(self.nearbyPostsKeys)
})
}
下面是我在 'viewDidLoad' 中调用该函数的方式:
populateNearbyAndPassIt{(nearbyPostsKeys) in
//populate 'posts' based on 'nearby..'
for key in nearbyPostsKeys {
let postRef = DataService.ds.REF_POSTS.queryOrdered(byChild: key)
postRef.observe(.value, with: { (snapshot) in
self.posts = []
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshot {
if let postDict = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
let post = Post(postKey: key, postData: postDict)
self.posts.append(post)
}
}
}
self.posts.reverse()
print("Zhenya: here are all local posts data: \(self.posts)")
})
}
}
虽然在指定位置有 3 个帖子,但发生了什么:
.observe 被调用。 1 个帖子被检索并附加到 nearbyPostsKeys -> 完成处理程序被调用。并传递了包含 1 个元素的数组...然后循环继续。
我希望我可以等到 'nearbyPostsKeys' 数组被填充,然后才将其作为完成处理程序传递。
我还了解了 .removeObserver
func 可以停止 .observe
func 但无论我把它放在哪里:
let newRefHandle: FIRDatabaseHandle = circleQuery!.observe(.keyEntered, with: { (key, location) in
self.nearbyPostsKeys.append(key!)
completion(self.nearbyPostsKeys)
})
circleQuery!.removeObserver(withFirebaseHandle: newRefHandle)
看起来 nearbyPostsKeys 根本没有传递。
请就更好的逻辑或如何使用提出建议 .removeObserver
。
谢谢你。
您应该在视图控制器取消初始化时删除观察者:
deinit {
circleQuery!.removeObserver(withFirebaseHandle: newRefHandle)
}
只需将 circleQuery
设为 viewcontroller 的 属性。
该应用应仅加载本地发布的帖子。
使用 GeoFire 在 FB 中有一个分支“posts_location
”。
我想先填充“nearbyPostsKeys
”数组,然后从 FB 的分支帖子中加载那些引用 REF_POSTS.
在 viewDidLoad
中,我调用了一个具有完成处理程序(来自 FB 的数据)的函数。
这是采用完成处理程序的 func 声明:
func populateNearbyAndPassIt(completion:@escaping ([String])->()) {
let theGeoFire = GeoFire(firebaseRef: DB_BASE.child("posts_location"))
let location = CLLocation(latitude: Location.sharedInstance.currentLatitude, longitude: Location.sharedInstance.currentLongitude)
let circleQuery = theGeoFire!.query(at: location, withRadius: 6.0)
let newRefHandle: FIRDatabaseHandle = circleQuery!.observe(.keyEntered, with: { (key, location) in
self.nearbyPostsKeys.append(key!)
completion(self.nearbyPostsKeys)
})
}
下面是我在 'viewDidLoad' 中调用该函数的方式:
populateNearbyAndPassIt{(nearbyPostsKeys) in
//populate 'posts' based on 'nearby..'
for key in nearbyPostsKeys {
let postRef = DataService.ds.REF_POSTS.queryOrdered(byChild: key)
postRef.observe(.value, with: { (snapshot) in
self.posts = []
if let snapshot = snapshot.children.allObjects as? [FIRDataSnapshot] {
for snap in snapshot {
if let postDict = snap.value as? Dictionary<String, AnyObject> {
let key = snap.key
let post = Post(postKey: key, postData: postDict)
self.posts.append(post)
}
}
}
self.posts.reverse()
print("Zhenya: here are all local posts data: \(self.posts)")
})
}
}
虽然在指定位置有 3 个帖子,但发生了什么:
.observe 被调用。 1 个帖子被检索并附加到 nearbyPostsKeys -> 完成处理程序被调用。并传递了包含 1 个元素的数组...然后循环继续。
我希望我可以等到 'nearbyPostsKeys' 数组被填充,然后才将其作为完成处理程序传递。
我还了解了 .removeObserver
func 可以停止 .observe
func 但无论我把它放在哪里:
let newRefHandle: FIRDatabaseHandle = circleQuery!.observe(.keyEntered, with: { (key, location) in
self.nearbyPostsKeys.append(key!)
completion(self.nearbyPostsKeys)
})
circleQuery!.removeObserver(withFirebaseHandle: newRefHandle)
看起来 nearbyPostsKeys 根本没有传递。
请就更好的逻辑或如何使用提出建议 .removeObserver
。
谢谢你。
您应该在视图控制器取消初始化时删除观察者:
deinit {
circleQuery!.removeObserver(withFirebaseHandle: newRefHandle)
}
只需将 circleQuery
设为 viewcontroller 的 属性。