Я часто сталкивался с этой ошибкой в моей OS X, используя swift:
«Это приложение модифицирует механизм автоматической разметки из фонового потока, что может привести к его повреждению и странным сбоям. Это приведет к исключению в будущем выпуске».
У меня есть NSWindow, и я поменялся местами в contentView
окне. Я получаю сообщение об ошибке, когда пытаюсь сделать NSApp.beginSheet
окно или добавить его subview
в окно. Пробовал отключать авторазмер, а у меня ничего не получается с помощью авторазметки. Есть предположения?
Иногда это нормально и ничего не происходит, иногда это полностью ломает меня UI
и ничего не загружается
swift
macos
autolayout
background-thread
отметка
источник
источник
Ответы:
Его нужно поместить в другой поток, который позволяет обновлять пользовательский интерфейс, как только выполнение функции потока завершается:
Современный Свифт:
Старые версии Swift, предварительно Swift 3.
Objective-C:
источник
Вы получаете похожее сообщение об ошибке при отладке с помощью операторов печати без использования dispatch_async. Поэтому, когда вы получаете это сообщение об ошибке, его время использовать
Swift 4
Свифт 3
Ранние версии Swift
источник
dispatch_async(dispatch_get_main_queue(), ^{ /* UI related code */ });
Редактировать: я обновил его ответ, там лучше работает форматирование синтаксиса.Ошибка «это приложение модифицирует механизм автоматической разметки из фонового потока» регистрируется в консоли задолго до того, как возникла реальная проблема, поэтому отладка может быть сложной без использования точки останова.
Я использовал ответ @ markussvensson, чтобы обнаружить мою проблему и нашел ее, используя эту символическую точку останова (Debug> Breakpoints> Create Symbolic Breakpoint):
[UIView layoutIfNeeded]
или[UIView updateConstraintsIfNeeded]
!(BOOL)[NSThread isMainThread]
Создайте и запустите приложение на эмуляторе и скопируйте шаги, которые приводят к выдаче сообщения об ошибке (приложение будет работать медленнее, чем обычно!). Затем Xcode остановит приложение и отметит строку кода (например, вызов функции), которая обращается к пользовательскому интерфейсу из фонового потока.
источник
movq 0x10880ba(%rip), %rsi ; "_wantsReapplicationOfAutoLayoutWithLayoutDirtyOnEntry:"
Когда вы пытаетесь обновить значение текстового поля или добавить подпредставление в фоновом потоке, вы можете получить эту проблему. По этой причине вы должны поместить этот вид кода в основной поток.
Вам нужно обернуть методы, которые вызывают обновления пользовательского интерфейса, в dispatch_asynch, чтобы получить основную очередь. Например:
РЕДАКТИРОВАНИЕ - SWIFT 3:
Теперь мы можем сделать это, следуя следующему коду:
источник
Для меня это сообщение об ошибке возникло из баннера от Admob SDK.
Я смог отследить источник до «WebThread», установив условную точку останова.
Тогда я смог избавиться от этой проблемы, заключив в капсулу создание Banner:
Я не знаю, почему это помогло, так как я не вижу, как этот код вызывался из не основного потока.
Надеюсь, это может кому-нибудь помочь.
источник
У меня была эта проблема с момента обновления до iOS 9 SDK, когда я вызывал блок, который делал обновления пользовательского интерфейса в обработчике завершения асинхронного запроса NSURLConnection. Помещение вызова блока в dispatch_async с использованием dispatch_main_queue решило проблему.
В iOS 8 все работало нормально.
источник
Была такая же проблема, потому что я использовал
performSelectorInBackground
.источник
Вы не должны менять пользовательский интерфейс вне основного потока! UIKit не является потокобезопасным, так что если вы сделаете это, то возникнет проблема, а также другие странные проблемы. Приложение может даже аварийно завершить работу.
Итак, чтобы выполнить операции UIKit, вам нужно определить блок и позволить ему выполняться в главной очереди: например,
источник
Очевидно, вы делаете некоторые обновления пользовательского интерфейса в фоновом потоке. Не могу предсказать, где именно, не видя ваш код.
Вот некоторые ситуации, которые могут произойти:
Вы могли бы делать что-то в фоновом потоке и не использовать. Находясь в той же функции, этот код легче обнаружить.
вызов функции, выполняющей вызов веб-запроса в фоновом потоке, и обработчик ее завершения; вызов другой функции, выполняющей обновление пользовательского интерфейса. Чтобы решить эту проблему, попробуйте проверить код, в котором вы обновили интерфейс после вызова веб-запроса.
источник
Основная проблема, связанная с тем, что «это приложение модифицирует механизм автоматической разметки из фонового потока», заключается в том, что оно, по-видимому, регистрируется долгое время после возникновения фактической проблемы, что может усложнить поиск и устранение неисправностей.
Мне удалось решить проблему, создав три символических контрольных точки.
Отладка> Точки останова> Создать символическую точку останова ...
Точка останова 1:
Условное обозначение:
-[UIView setNeedsLayout]
Состояние:
!(BOOL)[NSThread isMainThread]
Точка останова 2:
Условное обозначение:
-[UIView layoutIfNeeded]
Состояние:
!(BOOL)[NSThread isMainThread]
Точка останова 3:
Условное обозначение:
-[UIView updateConstraintsIfNeeded]
Состояние:
!(BOOL)[NSThread isMainThread]
С этими точками останова вы можете легко получить разрыв в реальной строке, где вы неправильно вызываете методы пользовательского интерфейса в неосновном потоке.
источник
У меня была эта проблема при перезагрузке данных в UITableView. Простая диспетчеризация перезагрузки, как это было решено для меня.
источник
У меня такая же проблема. Оказывается, я использовал для
UIAlerts
этого нужную основную очередь. Но они устарели .Когда я изменил
UIAlerts
кUIAlertController
, я больше не имел проблем и не должен использовать любойdispatch_async
код. Урок - обратите внимание на предупреждения. Они помогают, даже когда вы этого не ожидаете.источник
У вас уже есть правильный код ответа от @Mark, но просто для того, чтобы поделиться моими выводами: проблема в том, что вы запрашиваете изменение представления и предполагаете, что это произойдет мгновенно. В действительности загрузка представления зависит от доступных ресурсов. Если все загружается достаточно быстро и задержек нет, вы ничего не замечаете. В сценариях, где есть какая-либо задержка из-за занятости потока процесса и т. Д., Приложение сталкивается с ситуацией, когда оно должно что-то отображать, даже если оно еще не готово. Следовательно, желательно отправлять эти запросы в асинхронных очередях, чтобы они выполнялись в зависимости от нагрузки.
источник
У меня была эта проблема, когда я использовал TouchID, если это помогает кому-то еще, оберните вашу логику успеха, которая, вероятно, что-то делает с пользовательским интерфейсом в основной очереди.
источник
Это может быть что-то простое, например, установка значения текстового поля / метки или добавление подпредставления в фоновом потоке, что может привести к изменению макета поля. Убедитесь, что все, что вы делаете с интерфейсом, происходит только в главном потоке.
Проверьте эту ссылку: https://forums.developer.apple.com/thread/7399
источник
У меня возникла та же проблема при попытке обновить сообщение об ошибке в UILabel в том же ViewController (для обновления данных требуется некоторое время при попытке сделать это с помощью обычного кодирования). Я использовал
DispatchQueue
в Swift 3 Xcode 8, и это работает.источник
Если вы хотите отследить эту ошибку, используйте флажок pause on Issues для проверки основного потока. В большинстве случаев это легко исправить, отправив проблемную строку в основную очередь.
источник
Для меня проблема заключалась в следующем. Убедитесь, что
performSegueWithIdentifier:
выполняется в основном потоке:источник
Swift 4,
Предположим, если вы вызываете какой-либо метод, используя очередь операций
И предположим, что функция searchFavourites похожа на
если вы вызываете весь код внутри метода "searchFavourites" в главном потоке, он все равно выдаст ошибку, если вы обновите в нем какой-либо пользовательский интерфейс.
Так что используйте решение,
Для такого рода сценария.
источник
Вот проверить эту строку из журналов
вы можете проверить, какая функция вызывается из фонового потока или где вы вызываете метод API, вам нужно вызвать свою функцию из основного потока, как это.
Журналы здесь
источник
Я также столкнулся с этой проблемой, увидев тонну этих сообщений и следов стека, напечатанных на выходе, когда я изменил размер окна до меньшего размера, чем его первоначальное значение. Потратив долгое время на выяснение проблемы, я решил поделиться довольно простым решением. Я когда-то включил
Can Draw Concurrently
наNSTextView
сквозной IB. Это говорит AppKit, что он может вызыватьdraw(_:)
метод представления из другого потока. После его отключения я больше не получаю никаких сообщений об ошибках. У меня не возникало никаких проблем до обновления до MacOS 10.14 Beta, но в то же время я также начал изменять код для работы с текстовым представлением.источник