Перевірка головної нитки: API інтерфейсу викликається у фоновому потоці: - [UIApplication applicationState]


107

Я використовую карти Google в бета-версії Xcode 9, iOS 11.

Я отримую помилку, що виводиться в журнал наступним чином:

Перевірка головної нитки: API інтерфейсу викликається у фоновому потоці: - [UIApplication applicationState] PID: 4442, TID: 837820, ім'я теми: com.google.Maps.LabelingBehavior, Назва черги: com.apple.root.default-qos.overcommit , QoS: 21

Чому це трапляється, оскільки я майже впевнений, що я не змінюю жодних елементів інтерфейсу з основного потоку в коді.

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

1
У mapView(_:didChange)ви диспетчеризацію printзаяви в основну чергу. Ви вже не на головній черзі? Якщо ні, то вам також потрібно відправити animateдзвінок в основну чергу. Я б запропонував вставити кілька dispatchPrecondition(condition: .onQueue(.main))цих оновлень перед тим, як переконатися в цьому.
Роб

Ви сказали: "Я майже впевнений, що не змінюю жодних елементів інтерфейсу з головної нитки в коді". Я припускаю, що ви мали на увазі "... з будь-якої фонової нитки".
Роб

2
Не ваше питання. Я річ, що це в їх кінці. Він зупиняється в "com.google.Maps.LabelingBehavior". У мене така ж поблема.
Tarvo Mäesepp

2
Привіт, так, так, здається, проблема полягає в google, сподіваємось, вони незабаром
вийдуть

1
@MattBlack Погляньте на цей відповідь: stackoverflow.com/a/44392584/5912335
badhanganesh

Відповіді:


54

По-перше, переконайтеся, що ваші виклики карток Google та зміни інтерфейсу викликаються з головної нитки.

Ви можете дозволити засобу дезінфекції шукати рядки, що порушують.

Ви можете розмістити рядки, що ображають, на головну нитку з наступним:

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

Також оновіть свою поточну версію Google Maps. Карти Google повинні були зробити кілька оновлень для перевірки потоків.

На питання: "Чому це відбудеться?" Я думаю, що Apple додала твердження щодо кращого випадку, яке потім довелося оновити Google.


1
@thibautnoah, ти це кажеш, тому що я не охарактеризував це як "це (проблема) виникає через те, що ти використовуєш бета-код xcode 9 у поєднанні з API Google?" Або тому, що ви стикаєтеся з подібною помилкою, яку не вирішує моя відповідь?
ScottyBlades

7
Xcode 9 виділив деякі проблеми з потоком, які xcode 8, мабуть, не виявляє (чи потрібно це встановити через параметри xcode чи інша річ). Повернення назад до xcode 8 еквівалентне ігноруванню ваших проблем з ниткою, вони все ще є і не вирішені, тому це не рішення, ви просто закопуєте голову в пісок і робите вигляд, що все нормально. Якщо проблема надходить із рамки, будь ласка, надішліть її, щоб її можна було виправити.
thibaut noah

Xcode 9 виявляє проблеми з ниткою, які xcode 8 не дозволяє виявити, а Xcode 9 у поєднанні з API Google, ймовірно, викликає цю помилку. Ця помилка розміщена у відладчику для декількох збоїв І збоїв більше не відбувається, коли ви переходите до xcode 8.
ScottyBlades

Ви маєте на увазі те, що перевірка ниток виявляє симптом не причину. Я кажу, що бета Xcode 9 є і причиною, і комунікатором симптомів. "збої більше не трапляються, коли ви переходите до xcode 8". Існує різниця між попередженнями XCode і фактичними збоями при зчитуванні налагодження. Ця помилка може відображатись як попередження АБО або збій. Збій повністю припиняється при переході назад до xcode 8. Xcode 9 beta називається бета з поважної причини.
ScottyBlades

2
Так ... Я думаю, що багатьом розробникам ios важко бачити, що те, що щось проявляє симптом, не означає, що воно також не є причиною. Я думаю, що також важко визнати, що Apple, можливо, коли-небудь помилялася.
ScottyBlades

156

Важко знайти код інтерфейсу, який іноді не виконується в основному потоці. Ви можете використовувати трюк нижче, щоб знайти його та виправити.

  1. Виберіть "Редагувати схему" -> "Діагностика", поставте галочку для перевірки головної нитки.

    Xcode 11.4.1

    Клацніть маленьку стрілку поруч із засобом перевірки головної нитки, щоб створити точку розриву головної нитки перевірки. введіть тут опис зображення

    Попередній Xcode

    Поставте позначку "Пауза" з питань. введіть тут опис зображення

  2. Запустіть додаток iOS, щоб відтворити цю проблему. (Xcode повинен зробити паузу в першому номері.) введіть тут опис зображення

  3. Оберніть код, що модифікує інтерфейс користувача у DispatchQueue.main.async {} введіть тут опис зображення


4
Дякую, врятуй мене, можливо, 30 хвилин.
Помаранчевий

10
З якоїсь причини, коли я роблю це в Xcode 10.1, я отримую лише безпомилковий дзвінок, і я не можу зв’язатися з рядком коду: 2018-12-29 19: 46: 56.500629 + 0100 BedtimePrototype [1553: 834478] [звіти ] Перевірка головної теми: API інтерфейсу викликається у фоновому потоці: - [UIApplication applicationState] PID: 1553, TID: 834478, ім'я теми: com.apple.CoreMotion.MotionThread, назва черги: com.apple.root.default-qos. перевиконання, QoS: 0
Вілмір

1
Я також отримав стек дзвінків, який виглядає безпорадним. На лівій стороні він зупинився "com.apple.CoreMotion.MotionThread(23)", тоді я перевіряю і всі інші теми. В Thread 1ніж - то привернуло мою увагу: це SVProgressHUD (вид прогресу бібліотека я використовував). Отже, я знаю, що це дзвінок SVProgressHUD.show()кудись у контролер перегляду цілі. Потім або заверніть кожну появу, DispatchQueue.main.asyncабо просто прокоментуйте, протестуйте ще раз, і я з’ясував, який з них є проблематичним.
Джон Панг

2
Я також позбувся попередження, коментуючи SVProgressHUD.show. Переміщення цього дзвінка в DispatchQueue.main.async не позбулося попередження. Я використовую струк в v2.2.5 Цей потік може допомогти краще зрозуміти проблему: github.com/SVProgressHUD/SVProgressHUD/isissue/950
Vilmir

1
Не встановлено прапорець "Призупинити питання" для мене в xcode 11.4.1. Редагувати: Я знайшов маленьку стрілку поруч із головною тест-контролем. Клацання, що додає точку перерви для вас.
ChrisO

47

Оберніть рядки коду, що модифікують інтерфейс користувача DispatchQueue.main.async {}, щоб переконатися, що вони виконуються в основному потоці. В іншому випадку ви можете викликати їх із фонового потоку, де зміни інтерфейсу не дозволені. Усі такі рядки коду повинні виконуватися з основного потоку.


4
так, я вже використовував це, але попередження все ще присутнє
MattBlack

@Pang, він використовується для друку речей, а не для основного коду інтерфейсу.
Тома

4
@MattBlack спробуйте завершити все, що модифікує інтерфейс користувача,DispatchQueue.main.async {}
Тома

@ user6603599-Працює як шарм
Sree

3

Перейдіть за цим посиланням https://developer.apple.com/documentation/code_diagnostics/main_thread_checker

Для мене це спрацювало, коли я дзвонив з блоку.


1
Якщо ви використовуєте Swift 4+, це найкраще рішення, яке ідеально працює, дякую, що допомогли мені заощадити свій час. Я грав з редактором схем, але дотримуватися порад Apple - це найкращий варіант зараз і рухатися вперед.
AbuTaareq


-34

Виберіть схему -> Діагностика, зніміть перевірку основного потоку, тоді попередження зникне. редактор схем


18
Я не думаю, що це гарна ідея. Тут є проблема, яку виявила перевірка потоків. Якщо вимкнути перевірку ниток, це дозволить не розкрити цю та майбутні проблеми, а також призведе до виникнення майбутніх технічних боргів при вирішенні проблем.
ablarg

1
Насправді, я можу сказати, що ми можемо це зробити, коли використовуємо візуалізацію OpenGL es, оскільки ми не можемо відобразити буфер кадру в основному потоці. правильно?
Л.Пенг

1
Так, якщо попередження не з’являється, то проблеми не існує?
turingtest

11
"Чому мій детектор диму продовжує вимикатися?" "Просто вийміть акумулятор, проблема вирішена."
Джон Монтгомері

Якщо попередження не з’являється, проблема не існує?
С. Гіссел
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.