委托回调方法 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 方(应用程序委托)访问。
在我的应用委托 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 方(应用程序委托)访问。