【发布时间】:2018-12-28 13:48:50
【问题描述】:
大家好:我有一个通过 API 下载数据(纬度、经度)的函数,它可以 100% 正常工作。但问题是我想每 5 秒调用一次这个函数,在我添加一个计时器来执行此操作后,每次我尝试运行它时运行得非常好,5 秒后我崩溃了
unrecognized selector sent to instance 0x7ffa4a51cb00
2018-07-20 11:05:31.191467+0200 Interactive Bus[684:6752] ***
Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: '-[Interactive_Bus.MapVC
downloadBusDataWithUserId:warning:delegate:completed:]: unrecognized
selector sent to instance 0x7ffa4a51cb00'
我尝试清理然后构建并且没有代码错误我不知道为什么会发生这种崩溃
这是我的模型类
// busLocationModel.swift
// Interactive Bus
import UIKit
import Alamofire
import SwiftyJSON
class busLocationModel {
var route_pins: String?
var busLatitude: Double?
var busLongitude: Double?
@objc func downloadBusData(userId: String,warning: @escaping (String,String,String) -> Void, delegate : MapVC ,completed : @escaping DownloadCompleted) {
let Parameters = ["parent_id": userId]
print(#function)
Alamofire.request(busLocationUrl, method: .get, parameters: Parameters).responseJSON { (response) in
switch response.result {
case .failure(let error):
print(error)
let alertControllerTitle = "Warning"
let actionButtonTitle = "Ok"
let alertMessage = "Some Thing Went Wrong Please Try Agin Later "
return warning(alertControllerTitle, actionButtonTitle, alertMessage)
case .success(let Value):
let json = JSON(Value)
//print(json)
let status = json["status"].boolValue
if status != false {
for locations in json["data"].arrayValue {
let busPins = locations["route_pins"].stringValue
let bus_lat = locations["bus_lat"].doubleValue
let bus_long = locations["bus_long"].doubleValue
delegate.busPins = busPins
delegate.currentBusLate = bus_lat
delegate.currentBusLong = bus_long
print(delegate.busPins ?? "HH")
print("the bus lat is \(bus_lat)")
print("the bus long is \(bus_long)")
}
}
}
completed()
}
}
}
我的常量是:
typealias DownloadCompleted = () -> ()
我的 MapVC 是:
//
import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController {
@IBOutlet weak private var busMapView: MKMapView!
var locationManager = CLLocationManager()
//var locationManager: CLLocationManager!
let authorizationStatus = CLLocationManager.authorizationStatus()
fileprivate let regionRadius: Double = 1000 //Meter's From UP,Right,Down and Left
fileprivate var busInfoObject: busLocationModel!
var busPins: String!
var currentBusLate: CLLocationDegrees?
var currentBusLong: CLLocationDegrees?
var callFuncTimer: Timer!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
busMapView.delegate = self
busInfoObject = busLocationModel()
let myActivity = CreatActivityIndicator()
busInfoObject.downloadBusData(userId: "366", warning: DisplayAlertMessage, delegate: self) {
self.drawLine()
self.RemoveActivityIndicator(ActivityIndicator: myActivity)
guard let latitude = self.currentBusLate else { return }
guard let longitude = self.currentBusLong else { return }
let Location = CLLocation(latitude: latitude, longitude: longitude)
self.centerMapOnBusLocation(location: Location)
self.callFuncTimer = Timer.scheduledTimer(timeInterval: 5, target: self, selector: #selector(self.busInfoObject.downloadBusData(userId:warning:delegate:completed:)), userInfo: nil, repeats: true)
}
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
configureLocationServices()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(true)
callFuncTimer.invalidate()
}
@IBAction func centerMapBtnPressed(_ sender: Any) {
if authorizationStatus == .authorizedAlways {
guard let latitude = self.currentBusLate else { return }
guard let longitude = self.currentBusLong else { return }
let Location = CLLocation(latitude: latitude, longitude: longitude)
centerMapOnBusLocation(location: Location)
}
}
}
extension MapVC: MKMapViewDelegate {
fileprivate func centerMapOnBusLocation(location: CLLocation) {
//guard let currtntLocationCoordinate = locationManager.location?.coordinate else { return }
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate , regionRadius * 2.0, regionRadius * 2.0)
busMapView.setRegion(coordinateRegion, animated: true)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if (overlay is MKPolyline) {
let pr = MKPolylineRenderer(overlay: overlay)
pr.strokeColor = UIColor.blue
pr.lineWidth = 5
return pr
}
return MKPolylineRenderer()
}
}
extension MapVC {
func drawLine() {
let coordinates = busPins.components(separatedBy: "#").dropFirst().map { (pin) -> CLLocationCoordinate2D in
let latLng = pin.components(separatedBy: ",").map{ CLLocationDegrees($0)! }
return CLLocationCoordinate2D(latitude: latLng[0], longitude: latLng[1])
}
let polyLine = MKPolyline(coordinates: coordinates , count: coordinates.count)
self.busMapView.add(polyLine)
}
}
extension MapVC: CLLocationManagerDelegate {
fileprivate func configureLocationServices() {
if authorizationStatus == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else {
return
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard let latitude = self.currentBusLate else { return }
guard let longitude = self.currentBusLong else { return }
let Location = CLLocation(latitude: latitude, longitude: longitude)
centerMapOnBusLocation(location: Location)
}
}
这是 DisplayAlertMessage:
func DisplayAlertMessage(alertControllerTitle: String , actionButtonTitle: String , alertMessage: String) -> Void{
let alertcontroller = UIAlertController(title: alertControllerTitle, message: alertMessage , preferredStyle: .alert)
let okaction = UIAlertAction(title: actionButtonTitle, style: .default, handler: nil)
alertcontroller.addAction(okaction)
self.present(alertcontroller, animated: true, completion: nil)
}
我看不到代码错误我执行@OBJC 选择器语法是正确的,但我仍然收到错误(无法识别的选择器发送到实例)你能帮我吗??
【问题讨论】:
-
什么是被调用方法的参数中的“DisplayAlertMessage”?
-
仍然是同样的问题和同样的崩溃错误(无法识别的选择器发送到实例 0x7ffa4a51cb00)
-
DisplayAlertMessage: func DisplayAlertMessage(alertControllerTitle: String, actionButtonTitle: String, alertMessage: String) -> Void{ let alertcontroller = UIAlertController(title: alertControllerTitle, message: alertMessage, preferredStyle: .alert) let okaction = UIAlertAction(title: actionButtonTitle, style: .default, handler: nil) alertcontroller.addAction(okaction) self.present(alertcontroller, animated: true, completion: nil) }