Что такое проверка основного потока в Xcode

Я проверил, что нового в документации Xcode 9, и нашел это

введите описание изображения здесь

Но я не понимал, что это такое, как я могу использовать это с новым Xcode 9.


person Kishore Suthar    schedule 06.07.2017    source источник
comment
Вы пробовали простой поиск Google?   -  person deadbeef    schedule 06.07.2017
comment
Не нашел хорошо объясненного решения   -  person Kishore Suthar    schedule 06.07.2017
comment
developer.apple.com/documentation/code_diagnostics/   -  person deadbeef    schedule 06.07.2017
comment
решение, которое они предоставляют по ссылке devloper, уже доступно с xcode 8, а что нового - с xcode 9   -  person Kishore Suthar    schedule 06.07.2017
comment
Нет. Средство проверки основного потока не существует в Xcode 8   -  person deadbeef    schedule 06.07.2017
comment
Пожалуйста, попробуйте с xcode 8.3   -  person Kishore Suthar    schedule 06.07.2017
comment
developer.apple.com/videos/play/wwdc2017/406   -  person Hamish    schedule 06.07.2017


Ответы (4)


Его можно включить / отключить в опции диагностики схемы. Кроме того, «Пауза по проблемам» - удобный вариант для устранения этих проблем.

Xcode 11  введите описание изображения здесь

Xcode ‹11  Пример

person 93sauu    schedule 28.09.2017
comment
К сожалению, этой опции нет в Xcode 11. Вы знаете, где я могу ее найти? - person Chetan Hedamba; 05.02.2020
comment
Я обновил снимок экрана для Xcode 11. Единственное отличие состоит в том, что исчезла возможность приостанавливать работу при возникновении проблем. - person 93sauu; 05.02.2020
comment
Привет, я использую xcode 11.3, как я могу приостановить работу основного потока в xcode 11.3, пожалуйста, любое решение? - person MIOSY; 03.03.2020
comment
@MIOSY Я обновил захват для Xcode 11.3, отметив кнопку со стрелкой, чтобы добавить точку останова. - person 93sauu; 03.03.2020
comment
Единственное, что я получил в своем Xcode 11.3 во время выполнения, это :: Захват кадров графического процессора: данные о производительности шейдера могут быть недоступны из-за того, что целевой объект развертывания старше версии устройства. В моей консоли приложения он печатается как UIView setAnimationsEnabled вызывается из фонового потока. Выполнение любой операции из фонового потока в UIView или подклассе не поддерживается и может привести к неожиданному и коварному поведению после того, как пользовательский интерфейс моего приложения зависнет. Средство проверки основного потока не отправляется туда, где возникает проблема. Pls любое предложение ?? - person ; 04.03.2020
comment
@Rahul, возможно, вы представляете или настраиваете контроллер представления из фонового потока, поэтому отображается ошибка. Но поскольку ошибка из внешней библиотеки, точка останова не работает. Я советую раскомментировать код до тех пор, пока не появится ошибка, чтобы найти точную функцию или строку, вызываемую в фоновом потоке. Убедитесь, что вы вызываете правильный метод среды Dispatch, что является распространенной ошибкой - person 93sauu; 04.03.2020
comment
Вот исходный код для воспроизведения этой проблемы: диск. google.com/file/d/1FKHPO6SkdOEZ-w_GFnrU5CeeeMQrNT-h/ Вы просто запустите этот проект на устройстве и отсканируете изображение dinosaur.png (добавлено ion xcode), которое вы будете воспроизводить поверх него. Как только вы вернетесь к firstVC, и все приложение зависнет, вы не сможете нажать ни на одну кнопку в First VC, а также вы не сможете снова запустить сцену AR. Я не могу понять эту проблему, почему это происходит после просмотра GIF, вы можете проверить и сообщить мне. Если что-то потребуется, дайте мне знать .. Заранее спасибо. - person ; 04.03.2020
comment
Да, я тоже столкнулся с той же проблемой, Рахул. Пользовательский интерфейс завис из-за этой ошибки. @ 93sauu, пожалуйста, помогите нам. - person MIOSY; 04.03.2020
comment
Я просмотрел ваш код. Во-первых, метод ARSCNViewDelegate вызывается в фоновом потоке, поэтому, если вы хотите вызвать какой-либо метод UIKit, вам нужно вызвать его в основном потоке. С другой стороны, большая проблема в вашем коде заключается в том, что когда вы создаете материал с диффузным ответом, содержимое не может быть UIView (суперклассом GIFImageView). Содержимое материалов поддерживает только: UIColor, CGColor, NSNumber, UIImage и т. Д. Вы можете ознакомиться с документацией. - person 93sauu; 04.03.2020

Из документации Apple:

Main Thread Checker - это автономный инструмент для языков Swift и C, который обнаруживает недопустимое использование AppKit, UIKit и других API в фоновом потоке. Обновление пользовательского интерфейса в потоке, отличном от основного, является распространенной ошибкой, которая может привести к пропущенным обновлениям пользовательского интерфейса, визуальным дефектам, повреждению данных и сбоям.

Так, например, попытка изменить свойство text объекта UILabel в фоновом потоке не сработает. Apple утверждает, что это может привести к пропущенным обновлениям пользовательского интерфейса, визуальным дефектам, повреждению данных и сбоям. На практике в 99% случаев это приводит к случайным пропущенным обновлениям пользовательского интерфейса и визуальным дефектам (а не сбоям).

Сбои на самом деле были бы хороши, потому что мы могли бы легко обнаружить такое неправильное использование UIKit, но случайные визуальные дефекты гораздо труднее обнаружить во время разработки. И здесь на помощь приходит средство проверки основного потока.

Средство проверки основного потока поможет определить использование UIKit в фоновом потоке, оно не решит их. Как только вы обнаружили использование UIKit в фоновом потоке, вы можете решить эту проблему с помощью DispatchQueue.

Опять же, из документации Apple:

В документации URLSession говорится, что завершение завершения будет вызываться в фоновом потоке, так что это плохо, проверка основного потока поможет вам обнаружить использование UIKit в фоновом потоке.

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {      
      self.label.text = "\(data.count) bytes downloaded"
      // Error: label updated on background thread   
   }
}
task.resume()

Решение: используйте DispatchQueue.main для обновления пользовательского интерфейса в основном потоке.

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {
      DispatchQueue.main.async { // Correct
         self.label.text = "\(data.count) bytes downloaded"
      }
   }
}
task.resume()

Само решение не имеет ничего общего с Xcode, это особенность языка. Очевидно, это было возможно в предыдущих версиях Xcode, но до Xcode 9 у вас не было средства проверки основного потока, которое помогло бы обнаружить проблему.

Как указывает @hamish, вы также можете посмотреть видео WWDC, чтобы получить больше детальное объяснение.

person deadbeef    schedule 06.07.2017
comment
Есть ли способ отключить его для одного объекта в вашей программе? Кажется, он сообщает ерунду о том, что выполняется в основном потоке. - person Chewie The Chorkie; 19.04.2018
comment
Мне тоже интересно, знает ли кто-нибудь какие-либо диагностические команды pragma clang, чтобы отключить это предупреждение по очереди. - person Albert Renshaw; 07.12.2018
comment
Если вы включите этот инструмент, это приведет к тому, что задачи пользовательского интерфейса будут выполняться с задержкой, например, я пытался отобразить индикатор активности, и он появился после некоторой задержки, потому что он проверяет поток перед запуском каждой задачи UIKit. Кроме того, он не обнаруживал точно, например, хотя я работал в основном потоке, но он жаловался, что методы работают в фоновом режиме. - person i.AsifNoor; 03.10.2019

В разделе «Проверка API времени выполнения» убедитесь, что активирована Проверка основного потока, чтобы узнать, выполняете ли вы методы пользовательского интерфейса в потоке, отличном от пользовательского интерфейса.

введите описание изображения здесь

введите описание изображения здесь

person Sh_Khan    schedule 09.01.2018

В XCODE-12 перейдите к отладке, затем выберите «Схема», затем отредактируйте схему. Выберите «Выполнить» - ›Диагностика.

person Ahmed Nabeeh    schedule 04.07.2021
comment
Это то же решение, которое уже было представлено в принятом ответе. Если вы хотите улучшить принятый ответ, чтобы также упомянуть Xcode 12, вы можете сделать это, отредактировав его. - person JoRa; 05.07.2021
comment
буквально сказано в XCODE 12 в начале - person Ahmed Nabeeh; 19.07.2021