Swift:在结束时完成任务
试图将更改的值保留在闭包之外。在Swift:在结束时完成任务,swift,firebase,closures,Swift,Firebase,Closures,试图将更改的值保留在闭包之外。在observeSingleEvent()调用中从Firebase数据库中的子级分配length。但是,在函数之后,length的赋值不会保留在for循环中使用,而是使用初始值 此外,我将append() 如何在闭包中完成作业。我知道C++中可以使用和,如 [VARNAME] 通过引用。我们还没有发现与斯威夫特类似的东西 func loadMarkersFromDatabase(ref:DatabaseReference, node:String) -> [G
observeSingleEvent()
调用中从Firebase数据库中的子级分配length
。但是,在函数之后,length
的赋值不会保留在for循环中使用,而是使用初始值
此外,我将append()
如何在闭包中完成作业。我知道C++中可以使用<代码>和<代码>,如<代码> [VARNAME] 通过引用。我们还没有发现与斯威夫特类似的东西
func loadMarkersFromDatabase(ref:DatabaseReference, node:String) -> [GMSMarker] {
var markers = [GMSMarker]()
var length:Int? = 1
ref.child("Config").observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
length = (value?["AcademicBuildingsLength"] as? Int ?? 0)
})
print(length!)
for i in 0...length! {
ref.child(node).child(String(i)).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let building = value?["building"] as? String ?? ""
let lat = value?["lat"] as? Double ?? 0.0
let lon = value?["long"] as? Double ?? 0.0
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
marker.title = building
marker.snippet = node
markers.append(marker)
})
}
return markers
}
我曾尝试像这样添加一个闭包块[length]
,但随后出现以下编译错误:无法赋值:'length'是一个不可变的捕获
ref.child("Config").observeSingleEvent(of: .value, with: { [length](snapshot) in
let value = snapshot.value as? NSDictionary
length = (value?["AcademicBuildingsLength"] as? Int ?? 0)
})
闭包在另一个后台线程上异步执行。因此,不能在该块之外变异变量,可能必须使用完成闭包。要实现您想要的功能,您可以在闭包中调用另一个函数:
func loadMarkersFromDatabase(ref:DatabaseReference, node:String, completion: @escaping ([GMSMarker]) -> Void) {
ref.child("Config").observeSingleEvent(of: .value, with: { [length](snapshot) in
let value = snapshot.value as? NSDictionary
let markers = myFunction((value?["AcademicBuildingsLength"] as? Int ?? 0))
completion(markers)
}
}
然后:
func myFunction(length: Int) -> [GMSMarker] {
var markers: [GMSMarker] = []
for i in 0...length! {
ref.child(node).child(String(i)).observeSingleEvent(of: .value, with: { (snapshot) in
let value = snapshot.value as? NSDictionary
let building = value?["building"] as? String ?? ""
let lat = value?["lat"] as? Double ?? 0.0
let lon = value?["long"] as? Double ?? 0.0
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
marker.title = building
marker.snippet = node
markers.append(marker)
})
}
return markers
}
但是,在函数之后,长度的赋值不会保留以供使用
在for循环中,使用初始值
保留对标记的修改。问题是你对事物的执行顺序做出了错误的假设。假设执行闭包后,loadMarkersFromDatabase
函数返回“after”,但事实并非如此。observeSingleEvent
方法不会同步执行您给它的闭包,但会保留它以供以后执行。(您需要向它传递一个闭包的事实就是一个很好的提示;因为它是同步的,所以它可以直接返回快照,而不是将其传递到您的闭包中。)
如果将日志语句放在这两个位置,可以看到它们的实际执行顺序。当闭包运行时,它会将元素添加到标记
,共享对标记
访问权限的任何其他代码都会看到该更改。但是您没有使用它,因为您的loadMarkersFromDatabase
函数已经返回。调用loadMarkersFromDatabase(ref:node:completion)时,我需要完成什么?它调用一个函数,该函数接受一个gmsmarker列表,但不返回任何内容。没错,您需要传入一个函数,该函数接受一个gmsmarker数组,但不返回任何内容。