对于iOS Weather应用程序,我试图快速使用调度异步一一运行多个异步任务时遇到问题。我希望我的“update()”函数能够:

  • 获取用户的位置(并将纬度和经度存储在类变量中)
  • 定位服务完成后,根据新填充的经纬度变量
  • 调用天气API
    apit(和随后的XML解析)完成后,
  • ,更新UI(iOS表视图)

  • (请放心,我是一位自学成才的编码员,所以我假设那里经验丰富的人将能够指出各种错误!非常感谢您的帮助。)
        var latitude: String = ""
        var longitude: String = ""
        var locationManager: CLLocationManager!
        var forecastData: Weather = Weather() // the weather class has it's own asynchronous NSURLSession called retrieveForecast()
                                              // which calls the Open Weather Map API and parses the XML
    
        func refresh() {
            // Here's where I don't know what I'm doing:
            let group = dispatch_group_create()
            dispatch_group_enter(group)
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
                self.getLocation()
                dispatch_group_leave(group)
            }
            dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
                self.getWeather()
            }
            self.updateUI() // ...and I know that this is in totally the wrong place!
        }
    
    
        // function(s) to get phone's location:
        func getLocation() {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
            locationManager.requestWhenInUseAuthorization()
            locationManager.distanceFilter = 100.0
            locationManager.startUpdatingLocation()
        }
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            self.locationManager.stopUpdatingLocation()
            manager.stopUpdatingLocation()
            for item: AnyObject in locations {
                if let location = item as? CLLocation {
                    if location.horizontalAccuracy < 1000 {
                        manager.stopUpdatingLocation()
                        self.latitude = String(location.coordinate.latitude)
                        self.longitude = String(location.coordinate.longitude)
                    }
                }
            }
        }
    
        // function to download and parse the weather data within forecastData object
        func getWeather() {
                let apiCall = "http://api.openweathermap.org/data/2.5/forecast?lat=" + self.latitude
                + "&lon=" + self.longitude + "&mode=xml&appid=" + self.openWeatherMapAPIKey
            NSLog("getWeather called with api request: \(apiCall)")
            self.forecastData.retrieveForecast(apiCall)
        }
    

    最佳答案

    对于任何异步操作,拥有完成回调是一种好方法。
    在您的情况下,如果您已经实现了getLocationgetWeather的回调,则永远不需要dispatch_groups,您只需从getWeather的回调中调用getLocation,然后就可以从refreshUI的回调中调用getWeather

        var latitude: String = ""
        var longitude: String = ""
        var locationManager: CLLocationManager!
        var forecastData: Weather = Weather() // the weather class has it's own asynchronous NSURLSession called retrieveForecast()
                                              // which calls the Open Weather Map API and parses the XML
    
        func refresh() {
            self.getLocation()
        }
    
    
        // function(s) to get phone's location:
        func getLocation() {
            locationManager = CLLocationManager()
            locationManager.delegate = self
            locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
            locationManager.requestWhenInUseAuthorization()
            locationManager.distanceFilter = 100.0
            locationManager.startUpdatingLocation()
        }
        func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
            self.locationManager.stopUpdatingLocation()
            manager.stopUpdatingLocation()
            for item: AnyObject in locations {
                if let location = item as? CLLocation {
                    if location.horizontalAccuracy < 1000 {
                        manager.stopUpdatingLocation()
                        self.latitude = String(location.coordinate.latitude)
                        self.longitude = String(location.coordinate.longitude)
                        self.getWeather()
                    }
                }
            }
        }
    
        // function to download and parse the weather data within forecastData object
        func getWeather() {
                let apiCall = "http://api.openweathermap.org/data/2.5/forecast?lat=" + self.latitude
                + "&lon=" + self.longitude + "&mode=xml&appid=" + self.openWeatherMapAPIKey
            NSLog("getWeather called with api request: \(apiCall)")
            self.forecastData.retrieveForecast(apiCall)
            // assuming that self.forecastData.retrieveForecast(apiCall) is completely synchronous, we can call updateUI below
            self.updateUI()
        }
    

    这是代码,演示如何正确使用dispatch_group:
    func refetchOrdersAndChats(remoteNotificationData: [NSObject : AnyObject], completion: ((Bool)->())?) {
        var overallSuccess: Bool = true
        let refetchGroup = dispatch_group_create();
    
        dispatch_group_enter(refetchGroup);
        CPChatController.sharedInstance.updateChat(remoteNotificationData, completion: { success in
            overallSuccess = success && overallSuccess
            dispatch_group_leave(refetchGroup);
        })
    
        dispatch_group_enter(refetchGroup);
        CPChatController.sharedInstance.fetchNewOrdersWithNotification(remoteNotificationData, completion: { success in
            overallSuccess = success && overallSuccess
            dispatch_group_leave(refetchGroup);
        })
    
        dispatch_group_notify(refetchGroup,dispatch_get_main_queue(), {
            completion?(overallSuccess)
        })
    }
    

    07-28 01:54
    查看更多