125 votes

Vérificateur de fil principal : L'API de l'interface utilisateur est appelée sur un thread d'arrière-plan : -[UIApplication applicationState]

J'utilise google maps dans Xcode 9 beta, iOS 11.

Je reçois une erreur dans le journal comme suit :

Vérificateur de fil principal : API d'interface utilisateur appelée sur un thread d'arrière-plan : -[UIApplication applicationState] PID : 4442, TID : 837820, Nom du thread : com.google.Maps.LabelingBehavior, Nom de la file d'attente : com.apple.Root.default-qos.overcommit, QoS : 21

Pourquoi cela se produirait-il puisque je suis presque certain de ne pas modifier d'éléments d'interface depuis le fil principal dans mon code.

 override func viewDidLoad() {

    let locationManager = CLLocationManager()

    locationManager.requestAlwaysAuthorization()

    locationManager.requestWhenInUseAuthorization()

        if CLLocationManager.locationServicesEnabled() {

            locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
            locationManager.startUpdatingLocation()
        }

      viewMap.delegate = self

     let camera = GMSCameraPosition.camera(withLatitude: 53.7931183329367, longitude: -1.53649874031544, zoom: 17.0)

        viewMap.animate(to: camera)

    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let locValue:CLLocationCoordinate2D = manager.location!.coordinate
        print("locations = \(locValue.latitude) \(locValue.longitude)")
    }

    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {

    }

    func mapView(_ mapView: GMSMapView, idleAt position: GMSCameraPosition) {

        if(moving > 1){
            moving = 1
        UIView.animate(withDuration: 0.5, delay: 0, animations: {

            self.topBarConstraint.constant = self.topBarConstraint.constant + (self.topBar.bounds.height / 2)

            self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant + (self.topBar.bounds.height / 2)

            self.view.layoutIfNeeded()
        }, completion: nil)
    }
         moving = 1
    }

    // Camera change Position this methods will call every time
    func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
        moving = moving + 1
        if(moving == 2){

            UIView.animate(withDuration: 0.5, delay: 0, animations: {

                self.topBarConstraint.constant = self.topBarConstraint.constant - (self.topBar.bounds.height / 2)

                self.bottomHalfConstraint.constant = self.bottomHalfConstraint.constant - (self.topBar.bounds.height / 2)

                self.view.layoutIfNeeded()
            }, completion: nil)
        }
        DispatchQueue.main.async {

            print("Moving: \(moving) Latitude: \(self.viewMap.camera.target.latitude)")
            print("Moving: \(moving)  Longitude: \(self.viewMap.camera.target.longitude)")
        }
    }

172voto

Uncharted Works Points 56

Il est parfois difficile de trouver le code de l'interface utilisateur qui n'est pas exécuté dans le fil principal. Vous pouvez utiliser l'astuce ci-dessous pour le localiser et le corriger.

  1. Choisissez Edit Scheme -> Diagnostics, cochez Main Thread Checker et Pause on issues. enter image description here

  2. Exécutez votre application iOS pour reproduire ce problème. (Xcode devrait faire une pause au premier problème). enter image description here

  3. Enveloppez le code qui modifie l'IU dans DispatchQueue.main.async {} enter image description here

82voto

ScottyBlades Points 1262

Tout d'abord, assurez-vous que vos invocations de google maps et de modifications de l'interface utilisateur sont appelées depuis le thread principal en utilisant :

DispatchQueue.main.async {
    //Do UI Code here. 
    //Call Google maps methods.
}

Mettez également à jour votre version actuelle de Google Maps. Google Maps a dû faire quelques mises à jour pour le vérificateur de fil.

Pour la question : "Pourquoi cela se produit-il ?" Je pense qu'Apple a ajouté une assertion pour un cas limite pour lequel Google a dû mettre à jour son pod.

52voto

Enveloppez les lignes de code qui modifient l'interface utilisateur dans des fichiers DispatchQueue.main.async {} afin de s'assurer qu'ils s'exécutent sur le thread principal. Sinon, vous risquez de les appeler depuis un thread d'arrière-plan, où les modifications de l'interface utilisateur ne sont pas autorisées. Toutes ces lignes de code doivent être exécutées à partir du thread principal.

4voto

Consultez ce lien https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

Pour moi, cela a fonctionné lorsque j'ai appelé depuis le bloc.

0voto

gamal Points 517

Je pense que la solution est déjà donnée, Pour mon problème, c'est Keyboard qui est en route.

UIKeyboardTaskQueueue ne peut être appelé qu'à partir du thread principal.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X