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()
            }
        }
    }
}