Swift Cordova 中的插件导致 EXC_BAD_ACCESS
Swift plugin in Cordova causing EXC_BAD_ACCESS
我在 Swift 中为 Cordova 创建了一个自定义插件。一般来说它是 "working",因为我可以通过 JavaScript 与它通信。一切都很好,直到我尝试调用我的 类 之一中定义的方法。此时我在调用 locationService.authorizeLocationServices
方法时遇到 EXC_BAD_ACCESS 错误。
import Foundation
import CoreLocation
@objc(DBT) class DBT : CDVPlugin {
var locationService: LocationService = LocationService()
func authorizeLocationServices(_ command: CDVInvokedUrlCommand) {
let delegate = commandDelegate!
locationService.authorizeLocationServices(success: {
delegate.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "All OK"), callbackId:command.callbackId)
}, fail: {
delegate.send(CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not good, not good..."), callbackId:command.callbackId)
})
}
}
class LocationService : NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var authorizationSuccessCallback: (() -> ())?
var authorizationFailureCallback: (() -> ())?
override init() {
super.init()
locationManager.delegate = self
}
func authorizeLocationServices(success successCallback: @escaping () -> (), fail failureCallback: @escaping () -> ()) {
authorizationSuccessCallback = successCallback
authorizationFailureCallback = failureCallback
if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways {
locationManager.requestAlwaysAuthorization()
} else {
successCallback()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedAlways {
if let callback = authorizationSuccessCallback {
callback()
}
} else {
if let callback = authorizationFailureCallback {
callback()
}
}
}
}
我调试了一下代码,貌似是locationService
实例导致的,不知道为什么。
最终我解决了我的问题。由于未知原因,locationService
未实例化。所以我不得不把它变成一个可选类型,并在一个方法中实例化它。下面的代码按预期工作。
import Foundation
import CoreLocation
@objc(DBT) class DBT : CDVPlugin {
var locationService: LocationService?
func authorizeLocationServices(_ command: CDVInvokedUrlCommand) {
locationService = LocationService()
if let service = locationService {
service.authorizeLocationServices(success: {
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "All OK"), callbackId:command.callbackId)
}, fail: {
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not good, not good..."), callbackId:command.callbackId)
})
}
}
}
class LocationService : NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var authorizationSuccessCallback: (() -> ())?
var authorizationFailureCallback: (() -> ())?
override init() {
super.init()
locationManager.delegate = self
}
func authorizeLocationServices(success successCallback: @escaping () -> (), fail failureCallback: @escaping () -> ()) {
authorizationSuccessCallback = successCallback
authorizationFailureCallback = failureCallback
if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways {
locationManager.requestAlwaysAuthorization()
} else {
successCallback()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedAlways {
if let callback = authorizationSuccessCallback {
callback()
}
} else {
if let callback = authorizationFailureCallback {
callback()
}
}
}
}
我在 Swift 中为 Cordova 创建了一个自定义插件。一般来说它是 "working",因为我可以通过 JavaScript 与它通信。一切都很好,直到我尝试调用我的 类 之一中定义的方法。此时我在调用 locationService.authorizeLocationServices
方法时遇到 EXC_BAD_ACCESS 错误。
import Foundation
import CoreLocation
@objc(DBT) class DBT : CDVPlugin {
var locationService: LocationService = LocationService()
func authorizeLocationServices(_ command: CDVInvokedUrlCommand) {
let delegate = commandDelegate!
locationService.authorizeLocationServices(success: {
delegate.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "All OK"), callbackId:command.callbackId)
}, fail: {
delegate.send(CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not good, not good..."), callbackId:command.callbackId)
})
}
}
class LocationService : NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var authorizationSuccessCallback: (() -> ())?
var authorizationFailureCallback: (() -> ())?
override init() {
super.init()
locationManager.delegate = self
}
func authorizeLocationServices(success successCallback: @escaping () -> (), fail failureCallback: @escaping () -> ()) {
authorizationSuccessCallback = successCallback
authorizationFailureCallback = failureCallback
if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways {
locationManager.requestAlwaysAuthorization()
} else {
successCallback()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedAlways {
if let callback = authorizationSuccessCallback {
callback()
}
} else {
if let callback = authorizationFailureCallback {
callback()
}
}
}
}
我调试了一下代码,貌似是locationService
实例导致的,不知道为什么。
最终我解决了我的问题。由于未知原因,locationService
未实例化。所以我不得不把它变成一个可选类型,并在一个方法中实例化它。下面的代码按预期工作。
import Foundation
import CoreLocation
@objc(DBT) class DBT : CDVPlugin {
var locationService: LocationService?
func authorizeLocationServices(_ command: CDVInvokedUrlCommand) {
locationService = LocationService()
if let service = locationService {
service.authorizeLocationServices(success: {
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_OK, messageAs: "All OK"), callbackId:command.callbackId)
}, fail: {
self.commandDelegate!.send(CDVPluginResult(status: CDVCommandStatus_ERROR, messageAs: "Not good, not good..."), callbackId:command.callbackId)
})
}
}
}
class LocationService : NSObject, CLLocationManagerDelegate {
var locationManager = CLLocationManager()
var authorizationSuccessCallback: (() -> ())?
var authorizationFailureCallback: (() -> ())?
override init() {
super.init()
locationManager.delegate = self
}
func authorizeLocationServices(success successCallback: @escaping () -> (), fail failureCallback: @escaping () -> ()) {
authorizationSuccessCallback = successCallback
authorizationFailureCallback = failureCallback
if CLLocationManager.authorizationStatus() != CLAuthorizationStatus.authorizedAlways {
locationManager.requestAlwaysAuthorization()
} else {
successCallback()
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == CLAuthorizationStatus.authorizedAlways {
if let callback = authorizationSuccessCallback {
callback()
}
} else {
if let callback = authorizationFailureCallback {
callback()
}
}
}
}