在 class 中调用后委托 return nil
delegate return nil after calling it in a class
我正在使用此 class 获取位置并将其与委托一起发送到另一个视图控制器,但委托在调用时返回 nil。
我的 class:
protocol LocationUpdateProtocol {
func locationDidUpdateToLocation(location : CLLocation)
}
/// Notification on update of location. UserInfo contains CLLocation for key "location"
let kLocationDidChangeNotification = "LocationDidChangeNotification"
class LocationServiceHelper:NSObject,CLLocationManagerDelegate {
static let sharedManager = LocationServiceHelper()
private let locationManager = CLLocationManager()
var currentLocation:CLLocation?
weak var delegate :LocationUpdateProtocol?
private override init() {
super.init()
self.locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLLocationAccuracyHundredMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
// MARK: CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let delegate = self.delegate else {
return
}
currentLocation = locations.first
let userInfo:NSDictionary = ["location":currentLocation!]
delegate.locationDidUpdateToLocation(location: currentLocation!)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kLocationDidChangeNotification), object: self, userInfo: userInfo as? [AnyHashable : Any])
}
}
我在下面的另一个class中调用了代表:
var locationServiceReference = LocationServiceHelper.sharedManager
override func viewDidLoad() {
super.viewDidLoad()
fillFields()
locationServiceReference.delegate = self
self.mapView.showsUserLocation = true
}
func locationDidUpdateToLocation(location: CLLocation) {
// print(location)
// let myLocation = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let myLocationForTesting = CLLocationCoordinate2D(latitude: 33.410165, longitude: 35.480060)
myLocation = location
let region = MKCoordinateRegion(center: myLocationForTesting, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
}
在 did update location 中,委托返回 nil,知道发生了什么吗?该函数未被调用,因为委托返回 nil。
- 确保您的控制器仍在内存中
- 你不需要使用守卫。可选链接在这种情况下效果更好:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.first
let userInfo:NSDictionary = ["location":currentLocation!]
delegate?.locationDidUpdateToLocation(location: currentLocation!)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kLocationDidChangeNotification), object: self, userInfo: userInfo as? [AnyHashable : Any])
}
- 确保
func locationManager(_:didUpdateLocations)
在委托设置后调用。
- 对于未来,当委托更改为时,您希望传递最后一个位置:
weak var delegate :LocationUpdateProtocol? {
didSet {
guard let last = currentLocation else { return }
delegate?.locationDidUpdateToLocation(location: last)
}
}
- 因为它是只有 1 个委托的单例,请确保您没有将委托设置为
nil
或其他地方的另一个短寿命对象
这段代码-
var locationServiceReference = LocationServiceHelper.sharedManager
在你的 delegate
设置之前执行,这就是为什么 delegate
return nil
总是。
替换
var locationServiceReference = LocationServiceHelper.sharedManager
与
var locationServiceReference : LocationServiceHelper!
并在 viewDidLoad()
被调用后初始化。
override func viewDidLoad() {
super.viewDidLoad()
locationServiceReference = LocationServiceHelper.sharedManager
locationServiceReference.delegate = self
}
希望对您有所帮助。如果您还有任何问题,请告诉我。
我正在使用此 class 获取位置并将其与委托一起发送到另一个视图控制器,但委托在调用时返回 nil。 我的 class:
protocol LocationUpdateProtocol {
func locationDidUpdateToLocation(location : CLLocation)
}
/// Notification on update of location. UserInfo contains CLLocation for key "location"
let kLocationDidChangeNotification = "LocationDidChangeNotification"
class LocationServiceHelper:NSObject,CLLocationManagerDelegate {
static let sharedManager = LocationServiceHelper()
private let locationManager = CLLocationManager()
var currentLocation:CLLocation?
weak var delegate :LocationUpdateProtocol?
private override init() {
super.init()
self.locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLLocationAccuracyHundredMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
// MARK: CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let delegate = self.delegate else {
return
}
currentLocation = locations.first
let userInfo:NSDictionary = ["location":currentLocation!]
delegate.locationDidUpdateToLocation(location: currentLocation!)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kLocationDidChangeNotification), object: self, userInfo: userInfo as? [AnyHashable : Any])
}
}
我在下面的另一个class中调用了代表:
var locationServiceReference = LocationServiceHelper.sharedManager
override func viewDidLoad() {
super.viewDidLoad()
fillFields()
locationServiceReference.delegate = self
self.mapView.showsUserLocation = true
}
func locationDidUpdateToLocation(location: CLLocation) {
// print(location)
// let myLocation = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let myLocationForTesting = CLLocationCoordinate2D(latitude: 33.410165, longitude: 35.480060)
myLocation = location
let region = MKCoordinateRegion(center: myLocationForTesting, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
}
在 did update location 中,委托返回 nil,知道发生了什么吗?该函数未被调用,因为委托返回 nil。
- 确保您的控制器仍在内存中
- 你不需要使用守卫。可选链接在这种情况下效果更好:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
currentLocation = locations.first
let userInfo:NSDictionary = ["location":currentLocation!]
delegate?.locationDidUpdateToLocation(location: currentLocation!)
NotificationCenter.default.post(name: NSNotification.Name(rawValue: kLocationDidChangeNotification), object: self, userInfo: userInfo as? [AnyHashable : Any])
}
- 确保
func locationManager(_:didUpdateLocations)
在委托设置后调用。 - 对于未来,当委托更改为时,您希望传递最后一个位置:
weak var delegate :LocationUpdateProtocol? {
didSet {
guard let last = currentLocation else { return }
delegate?.locationDidUpdateToLocation(location: last)
}
}
- 因为它是只有 1 个委托的单例,请确保您没有将委托设置为
nil
或其他地方的另一个短寿命对象
这段代码-
var locationServiceReference = LocationServiceHelper.sharedManager
在你的 delegate
设置之前执行,这就是为什么 delegate
return nil
总是。
替换
var locationServiceReference = LocationServiceHelper.sharedManager
与
var locationServiceReference : LocationServiceHelper!
并在 viewDidLoad()
被调用后初始化。
override func viewDidLoad() {
super.viewDidLoad()
locationServiceReference = LocationServiceHelper.sharedManager
locationServiceReference.delegate = self
}
希望对您有所帮助。如果您还有任何问题,请告诉我。