意外的双重函数调用[重复]

Posted

技术标签:

【中文标题】意外的双重函数调用[重复]【英文标题】:unexpected double func call [duplicate] 【发布时间】:2018-07-19 20:04:24 【问题描述】:

我有一个手势可以在地图上添加一个图钉,当我添加该图钉时,我会进行地理编码以获取该图钉地址。 问题是每次我触摸地图添加一个图钉时,它都会无缘无故地调用我的手势函数两次

每次触摸地图都会调用两次print("city:", placemark.locality ?? "")

class PlaceYourPinpointViewController: UIViewController, UIGestureRecognizerDelegate 

    // MARK: - Variables

    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var nextBarButton: UIBarButtonItem!
    @IBOutlet weak var textView: UITextView!
    let annotation = MKPointAnnotation()

    var newLocation = CLLocation()
    let geocoder = CLGeocoder()
    var placemark: CLPlacemark?

    var addAnnotationGesture = UILongPressGestureRecognizer()
    var panGesture = UIPanGestureRecognizer()

    // MARK: - ios Basic

    override func viewDidLoad() 
        super.viewDidLoad()
        addPinGesture()
        didDragMap()
        removePinGesture()
    

    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        setLaunchZoom()
    

    // MARK: - Actions

    @IBAction func cancel() 
        dismiss(animated: true, completion: nil)
    

    @objc func addPin(gestureRecognizer: UIGestureRecognizer) 
        let touchPoint = gestureRecognizer.location(in: mapView)
        let newCoordinates = mapView.convert(touchPoint, toCoordinateFrom: mapView)

        annotation.coordinate = newCoordinates
        self.mapView.addAnnotation(annotation)

        geocode(latitude: annotation.coordinate.latitude, longitude: annotation.coordinate.longitude)  placemark, error in
            guard let placemark = placemark, error == nil else  return 
            // you should always update your UI in the main thread
                print("city:", placemark.locality ?? "")
                self.textView.text = self.string(from: placemark)
        
        nextBarButton.isEnabled = true
    

    @objc func removePin(gestureRecognizer: UIGestureRecognizer) 
        self.mapView.removeAnnotation(annotation)
    

    // MARK: - Private Methods

    func addPinGesture() 
        addAnnotationGesture = UILongPressGestureRecognizer(target: self, action: #selector(addPin))
        addAnnotationGesture.minimumPressDuration = 0.06
        mapView.addGestureRecognizer(addAnnotationGesture)
    

    func removePinGesture() 
        let removeAnnotationGesture = UITapGestureRecognizer(target: self, action: #selector(removePin))
        removeAnnotationGesture.numberOfTapsRequired = 1
        self.mapView.addGestureRecognizer(removeAnnotationGesture)
    

    func didDragMap() 
        panGesture = UIPanGestureRecognizer(target: self, action: nil)
        panGesture.delegate = self
        mapView.addGestureRecognizer(panGesture)
    

    func setLaunchZoom() 
        let region = MKCoordinateRegion(center: mapView.userLocation.coordinate, latitudinalMeters: 600, longitudinalMeters: 600)
        mapView.setRegion(mapView.regionThatFits(region), animated: true)
    

    func string(from placemark: CLPlacemark) -> String 
        // make address label

        var line = ""
        line.add(text: placemark.subThoroughfare)
        line.add(text: placemark.thoroughfare, separatedBy: " ")
        line.add(text: placemark.locality, separatedBy: ", ")
        line.add(text: placemark.country, separatedBy: ", ")
        line.add(text: placemark.postalCode, separatedBy: ", ")
        return line
    

    func geocode(latitude: CLLocationDegrees, longitude: CLLocationDegrees, completion: @escaping (CLPlacemark?, Error?) -> ())  
        CLGeocoder().reverseGeocodeLocation(CLLocation(latitude: latitude, longitude: longitude))  placemarks, error in
            guard let placemark = placemarks?.first, error == nil else 
                completion(nil, error)
                return
            
            completion(placemark, nil)
        
    

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool 
        // Do not begin the long press unless the pan fails.
        if gestureRecognizer == self.panGesture && otherGestureRecognizer == self.addAnnotationGesture 
            return true
        
        return false
    

【问题讨论】:

【参考方案1】:

手势具有您必须在开始或结束时调用它的状态

@objc func addPin(gestureRecognizer: UIGestureRecognizer)    
   if gestureRecognizer.state != .began 
     return 
  

【讨论】:

谢谢它的工作,你有地理编码的知识吗,因为在地图上添加了一些图钉后,它会停止在标签上显示地址,1分钟后它再次工作我不明白 可能是地理编码器在对位置进行地理编码时返回零数据,添加打印语句并在函数中检查 它永远不会是零。为什么它会工作一段时间然后停止并再次工作,这是没有意义的 请注意,地理编码器是异步的,这意味着在获取位置数据之前应该有一个延迟 我明白这一点,但延迟大约 1 分钟对您来说是正常的吗?

以上是关于意外的双重函数调用[重复]的主要内容,如果未能解决你的问题,请参考以下文章

函数调用中的意外编译错误(C++)[关闭]

C++意外调用继承类的函数

WCF 跟踪在使用 JSONP 的调用函数上引发 XML 异常“遇到意外字符'j'”

二维数组与双重指针

在 C++ 中使用 istringstream 进行字符串到双重转换的意外结果

可重入函数和不可重入函数