【问题标题】:Wait for Asynchronous Function to Complete等待异步函数完成
【发布时间】:2015-01-11 09:32:22
【问题描述】:

位置管理器需要一段时间来查询一个包含 10000 行的类(在 Parse 中)。 我试图阻止用户在查询完成之前选择一行(在 tableViewController 中)。 在允许选择之前强制用户等待查询完成的最佳方式是什么?

查询加载数据:

func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
    CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
        if (error != nil) {
            println("Error:" + error.localizedDescription)
        }
        if placemarks.count > 0 {
            let pm = placemarks[0] as CLPlacemark
            self.displayLocationInfo(pm)
            currentLoc = manager.location
            currentLocGeoPoint = PFGeoPoint(location:currentLoc)

            var query = PFQuery(className:"test10000")
            query.whereKey("RestaurantLoc", nearGeoPoint:currentLocGeoPoint, withinMiles:10) //filter by miles
            query.limit = 1000 //limit number of results
            query.findObjectsInBackgroundWithBlock {
                (objects: [AnyObject]!, error: NSError!) -> Void in
                if objects != nil {
                    unfilteredRestaurantArray = objects
                } else {
                    println("error: \(error)")
                }
            }

        } else {
            println("error: \(error)")
        }
    })
}

其他信息:

程序使用带有segues的didSelectRowAtIndex:

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if indexPath.row == 0 {
        self.performSegueWithIdentifier("toQ2", sender: self)
    } else {
        self.performSegueWithIdentifier("toQ1", sender: self)
    }

viewDidLoad 调用 locationManager:

override func viewDidLoad() {
    self.locationManager.delegate = self //location manager start
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
    self.locationManager.requestWhenInUseAuthorization()
    self.locationManager.startUpdatingLocation()
}

【问题讨论】:

    标签: objective-c swift asynchronous parse-platform


    【解决方案1】:

    为自己定义一个变量,表明查询仍在运行。启动查询时,禁用与表的任何交互或在其上放置带有活动指示器的覆盖。要在查询完成时收到通知,您可以使用 didSet 挂钩,例如

    var queryIsRunning : Bool { didSet { onQueryIsRunningChanged() } }
    
    [...]
    
    func onQueryIsRunningChanged()
    {
        if queryIsRunning
        {
            // Code to disable user interactions
        }
        else
        {
            // Code to re-enable user interactions
        }
    }
    

    也许需要从主线程设置变量,这可以通过

    dispatch_async(dispatch_get_main_queue(), { self.queryIsRunning = queryIsRunningState } )
    

    【讨论】:

    • 感谢您的回答。使用queryIsRunning = false//true就足够了,还是需要使用 didSet 钩子?
    • 另外,您介意解释一下 dispatch_async 的用途以及我将其放置在哪里吗?提前致谢:)
    • 变量:你只需分配给queryIsRunning,钩子就会自动调用。调度:假设您的查询在另一个线程中运行,但表使用主线程,dispatch_async 确保钩子将在主线程上执行。如果查询和表使用相同的线程,则不需要这样做。
    • 好的,我明白了。但是,我在添加 queryIsRunning 块时不断产生错误。 i.imgur.com/qAgkz4L.png我是不是执行错了?
    • 那是因为变量没有初始化。您必须实现 init 函数,也适用于 NSCoding(参见 Swift: Class does not implement its superclass's required members)。您可以通过直接初始化变量来规避这种情况,例如var queryIsRunning : Bool = false { ... }
    猜你喜欢
    • 2019-06-16
    • 2019-11-29
    • 2023-03-10
    • 2020-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    相关资源
    最近更新 更多