完成阻止问题

时间:2018-01-18 09:58:27

标签: ios swift

好的,我有一个潜在的问题,我需要帮助/建议。我有两个函数可以从我的数据库中提取密钥,然后将这些密钥传递给另一个最终获取所有数据的函数。

这是第一个功能

static func showEvent(for currentLocation: CLLocation,completion: @escaping ([Event]) -> Void) {
    //getting firebase root directory
    var currentEvents = [Event]()
    var geoFireRef: DatabaseReference?
    var geoFire:GeoFire?
    geoFireRef = Database.database().reference().child("eventsbylocation")
     geoFire = GeoFire(firebaseRef: geoFireRef)
    let circleQuery = geoFire?.query(at: currentLocation, withRadius: 10.0)
    circleQuery?.observe(.keyEntered, with: { (key: String!, location: CLLocation!) in
        print("Key '\(key)' entered the search area and is at location '\(location)'")
        EventService.show(forEventKey: key, completion: { (event) in
            currentEvents.append(event!)
            completion(currentEvents)
        })
    })

}

此函数使用EventService.show函数最终获取前面提到的数据。

 static func show(forEventKey eventKey: String, completion: @escaping (Event?) -> Void) {
        // print(eventKey)
        let ref = Database.database().reference().child("events").child(eventKey)
         print(eventKey)
        //pull everything
        ref.observeSingleEvent(of: .value, andPreviousSiblingKeyWith: { (snapshot,eventKey) in
            //print(snapshot.value ?? "")
            guard let event = Event(snapshot: snapshot) else {
                return completion(nil)
            }
           completion(event)
        })
    }

当这两个函数都完成后,它会返回我的main函数,并使用事件数组来帮助填充我的collectionView。

这是该功能

@objc func grabUserLoc(){
    LocationService.getUserLocation { (location) in
        guard let currentLocation = location else {
            return
        }
        PostService.showEvent(for: currentLocation, completion: { (events) in
            self.allEvents = events
            print("Event count in PostService Closure:\(self.allEvents.count)")
            self.dynamoCollectionView.reloadData()
        }
        )
        print("Latitude: \(currentLocation.coordinate.latitude)")
        print("Longitude: \(currentLocation.coordinate.longitude)")
    }

}

现在跟踪堆栈时,我发现多次调用reloadData。有什么方法可以解决这些功能,以便在拉出所有数据时实际完成块。所以reloadData只被调用一次,而不是每次都有一个事件的实例回来?

我希望我的问题有道理 DispatchGroups引起了我的注意,任何人都可以向我展示一个答案的实现

1 个答案:

答案 0 :(得分:0)

取自我评论中的文章:

let dispatchGroup = DispatchGroup()

dispatchGroup.enter()
longRunningFunction { dispatchGroup.leave() }

dispatchGroup.enter()
longRunningFunctionTwo { dispatchGroup.leave() }

dispatchGroup.notify(queue: .main) {
    print("Both functions complete ")
}

您在进入该组的每个Async活动中创建一个组,当该异步活动完成后,您离开该组,当调度组离开时,它将调用通知。

编辑:

因此,在您的情况下,您可以将组传递给funcs,在完成时离开,或者让每个func都有一个可选的完成,然后将其调回原始组以离开组。