Swift中如何在callTestArray()调用locationManager()内的testArray?
解决在callTestArray()中访问locationManager回调里testArray为nil的问题
看起来你碰到了两个核心问题:一是方法内的局部变量外部访问不到,二是异步操作导致数组还没赋值就被访问了。我来一步步帮你解决:
1. 先搞定变量作用域问题
你在locationManager(_:didUpdateLocations:)里声明的testArray是局部变量,只有这个方法内部能访问,外部的callTestArray()根本看不到它。所以第一步要把它移到类的顶部,作为实例变量,并且初始化(别让它默认是nil):
class YourLocationClass: CLLocationManagerDelegate { // 替换成你实际需要的数据类型,比如[String]或者自定义模型 var testArray: [Any] = [] let locationManager = CLLocationManager() // 其他初始化代码... }
2. 处理异步加载的坑
GeoFire的查询是异步操作——也就是说,当你调用query.observe(...)的时候,代码会继续往下走,不会等查询结果返回。如果你在callTestArray()里直接访问testArray,大概率此时查询还没完成,数组自然是空的。
正确的做法是:在GeoFire的回调里给testArray赋值,并且在赋值完成后再调用callTestArray()(或者用闭包通知):
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let userLocation = locations.first else { print("获取不到用户位置") return } let rootRef = Database.database().reference() let geoRef = GeoFire(firebaseRef: rootRef.child("X")) // 这里替换成你实际的半径值 let query = geoRef.query(at: userLocation, withRadius: 500) // 监听GeoFire的查询结果(这里用keyEntered举例,根据你的需求换事件类型) query.observe(.keyEntered) { (key, location) in // 注意:网络回调默认在后台线程,如果要更新UI或者操作UI相关的数据,切回主线程 DispatchQueue.main.async { // 把查询到的数据添加到testArray里,替换成你实际要存的内容 self.testArray.append(key) // 数据更新完成后,再调用callTestArray() self.callTestArray() } } }
3. 完善callTestArray()的逻辑
现在callTestArray()可以正确访问到有数据的testArray了,你可以在里面处理数据:
func callTestArray() { guard !testArray.isEmpty else { print("testArray还没有数据,可能查询还在进行或者没有匹配结果") return } // 这里写你处理testArray的逻辑 print("拿到的testArray内容:\(testArray)") }
额外注意事项
- 确保你的
CLLocationManager已经正确设置了delegate,并且获取了位置权限,否则locationManager(_:didUpdateLocations:)根本不会被调用,testArray自然不会有数据。 - 如果是一次性查询,你可以用
query.observeSingleEvent(of: .value)代替observe(.keyEntered),避免重复监听。 - 如果需要每次查询都清空旧数据,记得在GeoFire回调前先执行
self.testArray.removeAll()。
内容的提问来源于stack exchange,提问作者RTNTVG
相关产品推荐
相关产品推荐

