Używam map Google w Xcode 9 beta, iOS 11.
Otrzymuję następujący błąd w dzienniku:
Kontroler głównego wątku: UI API wywołane w wątku w tle: - [UIApplication applicationState] PID: 4442, TID: 837820, nazwa wątku: com.google.Maps.LabelingBehavior, nazwa kolejki: com.apple.root.default-qos.overcommit , QoS: 21
Dlaczego tak się dzieje, ponieważ jestem prawie pewien, że nie zmieniam żadnych elementów interfejsu z głównego wątku w moim kodzie.
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)")
}
}
swift
google-maps
xcode9-beta
Czarny matowy
źródło
źródło
mapView(_:didChange)
jesteś wysłaniemprint
oświadczenia do głównej kolejki. Nie jesteś już w głównej kolejce? Jeśli nie, musisz również wysłaćanimate
połączenie do głównej kolejki. Sugerowałbym wstawienie kilkudispatchPrecondition(condition: .onQueue(.main))
przed aktualizacjami interfejsu użytkownika, aby się upewnić.Odpowiedzi:
Po pierwsze, upewnij się, że wywołania map google i zmiany interfejsu użytkownika są wywoływane z głównego wątku.
Możesz włączyć program Thread Sanitizer, aby znaleźć obraźliwe wiersze.
Możesz umieścić obraźliwe wiersze w głównym wątku za pomocą:
Zaktualizuj również swoją aktualną wersję map Google. Mapy Google musiały dokonać kilku aktualizacji sprawdzania wątków.
Na pytanie: „Dlaczego tak się dzieje?” Myślę, że Apple dodał twierdzenie o przypadku krawędzi, dla którego Google musiał zaktualizować swój pod.
źródło
Trudno jest znaleźć kod UI, który czasami nie jest wykonywany w głównym wątku. Możesz użyć poniższej sztuczki, aby go zlokalizować i naprawić.
Wybierz Edit Scheme -> Diagnostics, zaznacz Main Thread Checker.
Xcode 11.4.1
Kliknij małą strzałkę obok głównego kontrolera wątków, aby utworzyć punkt przerwania głównego kontrolera wątków.
Poprzedni Xcode
Zaznacz opcję Wstrzymaj w przypadku problemów.
Uruchom aplikację na iOS, aby odtworzyć ten problem. (Xcode powinien zatrzymać się przy pierwszym numerze).
Zawiń kod, który modyfikuje interfejs użytkownika w
DispatchQueue.main.async {}
źródło
"com.apple.CoreMotion.MotionThread(23)"
, potem sprawdzam też wszystkie inne wątki. WThread 1
czymś zwróciło moją uwagę: jest to SVProgressHUD (biblioteka widoku postępu, z której korzystałem). Więc wiem, że to wywołanieSVProgressHUD.show()
gdzieś w docelowym kontrolerze widoku. Następnie zawiń każdy wyglądDispatchQueue.main.async
lub po prostu skomentuj, przetestuj ponownie i odkryłem, który z nich jest problematyczny.Zawiń wiersze kodu, które modyfikują interfejs użytkownika
DispatchQueue.main.async {}
, aby upewnić się, że są wykonywane w głównym wątku. W przeciwnym razie możesz wywoływać je z wątku w tle, w którym modyfikacje interfejsu użytkownika są niedozwolone. Wszystkie takie wiersze kodu muszą być wykonywane z głównego wątku.źródło
DispatchQueue.main.async {}
Skorzystaj z linku https://developer.apple.com/documentation/code_diagnostics/main_thread_checker
U mnie to zadziałało, gdy zadzwoniłem z bloku.
źródło
Myślę, że rozwiązanie jest już podane, ponieważ mój problem to klawiatura w drodze.
UIKeyboardTaskQueue można wywołać tylko z głównego wątku
źródło
Wybierz schemat -> Diagnotics, usuń główny kontroler wątków, a ostrzeżenie zniknie. edytor schematów
źródło