委托回调方法 returns 变慢导致从另一个 class 访问时变量为 nil?

Delegate Call back method returns variable slow which causes variable nil while accessing from another class?

在我的应用委托 class 中,我正在尝试使用委托从另一个 class 检索用户当前位置。这个检索到的User Curren位置将在我的application.So的许多地方使用,我已经在AppDelegate Class

中设置了它
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var helperLocation:HelperLocationManager?
    var currentLocation:CLLocation?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        //get the current location and set it so all other screens can use it
        self.helperLocation = HelperLocationManager()
        self.helperLocation?.delegate = self 
        return true
    }
}

   extension AppDelegate: SendLocationDelegate{

     func sendCoOrdinates(loccoordinate:CLLocation, placemark:CLPlacemark){
             currentLocation = loccoordinate
      }
    }

这似乎是我的 HelperLocationManager Class

protocol SendLocationDelegate{

    func sendCoOrdinates(coordinates:CLLocation,placemark:CLPlacemark)

}

class HelperLocationManager: NSObject {

    var locationManager = CLLocationManager()
    var delegate:SendLocationDelegate?

    override init() {

        super.init()

        var code = CLLocationManager.authorizationStatus()

        if code == CLAuthorizationStatus.NotDetermined {

            locationManager.requestAlwaysAuthorization()
            locationManager.requestWhenInUseAuthorization()

        }

        locationManager.delegate = self

    }


}


extension HelperLocationManager: CLLocationManagerDelegate{


    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {

        switch status {

        case CLAuthorizationStatus.Restricted:

            println( "Restricted Access to location")

        case CLAuthorizationStatus.Denied:

            println( "User denied access to location please turn on the location")
            // UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString)!)
            //may be open here settings page and say to turn on the setting location services


        default:

            locationManager.startUpdatingLocation()
        }

    }

    func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

        var locValue = locations.last as! CLLocation
        locationManager.stopUpdatingLocation()

        CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: {(placemarks,error)-> Void in

            if (error != nil) {
                println("Reverse geocoder failed with error" + error.localizedDescription)
                return
            }

            if placemarks.count > 0 {

                let pm = placemarks[0] as! CLPlacemark
                self.delegate?.sendCoOrdinates(locValue,placemark: pm)

            } else {

                println("Problem with the data received from geocoder")
            }
        })


    }


    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {

        println("Your error is ", error.localizedDescription)

    }

}

如果用户位置发生任何变化,我会触发我的回调方法...

一切都很好。 HelperLocationManager class 将当前位置发送到 AppDelegate 中实现的方法 sendCoOrdinates 我已经设置了当前位置,现在我从 [=20= 访问这些位置] 作为

 let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
 pickUpDistanceLocation = appDelegate.currentLocation

我的问题是,当我尝试在另一个 class 中以足够快的速度访问该值时,委托回调方法不会向我发送我当前的 Location.I 在此 case.but 如果我等待 2-3 秒然后转到另一个 class 我从委托那里得到值。

谁能解释一下我做错了什么?

这是一个架构问题 - 你说:

when i try to access the value very fast enough in another class during the time interval the delegate call back method does not send me my current Location

你必须反转 - 而不是检查当前位置,因为它还没有被获取的风险,你应该让 HelperLocationManager 在它有位置时通知(好莱坞原则:不叫我,我叫你).

这可以通过不同的方式完成:

  • 使用委托模式
  • 使用事件总线(可以用NSNotificationCenter实现)
  • 使用回调

当然还有很多其他方法可以达到同样的效果。

当有多个观察者时,委托模式可能不是最佳解决方案。

我会使用回调方式,订阅者通过向 HelperLocationManager 提供闭包来注册位置更新。

HelperLocationManager 可以将所有回调存储到一个数组中,并在位置更新可用时调用每个回调。或者,如果位置已经可用,它可以在注册后立即调用闭包。

最后,订阅者必须能够取消订阅,因此 HelperLocationManager 应该公开一个方法,从其内部列表中删除回调。

这只是一个想法 - 如前所述,它可以通过多种不同的方式完成,常见的规则是反转位置的传递方式。

注意:我会将 HelperLocationManager 设为单例,然后将其从 AppDelegate 中删除。如果我想使用 HelperLocationManager,我应该直接联系它,而不是必须通过第 3 方(应用程序委托)访问。