Получение "Это приложение изменяет ошибку автозапуска из фонового потока"?
Очень часто сталкивалась с этой ошибкой в моей ОС X с помощью быстрой:
"Это приложение изменяет механизм автозапуска из фонового потока, что может привести к повреждению двигателя и странным сбоям. Это приведет к исключению в будущей версии".
У меня есть мой NSWindow, и я обмениваюсь представлениями в contentView
окна. Я получаю ошибку при попытке сделать NSApp.beginSheet
в окне или когда я добавляю subview
к окну. Попробовал отключить функцию авторазрешения, и у меня нет ничего с помощью автоматического макета. Любые мысли?
Иногда это нормально, и ничего не происходит, в других случаях он полностью разбивает мой UI
и ничего не загружает
Ответы
Ответ 1
Хорошо - нашел ответ. Он должен быть помещен в другой поток, который позволяет обновлять пользовательский интерфейс, как только выполнение функции потока завершается:
Swift 3
DispatchQueue.main.async {
// Update UI
}
Swift Version < 3
dispatch_async(dispatch_get_main_queue(){
// code here
})
Objective-C Версия
dispatch_async(dispatch_get_main_queue(), ^{
// code here
});
Ответ 2
Аналогичное сообщение об ошибке появляется при отладке с помощью операторов печати без использования "dispatch_async". Поэтому, когда вы получаете это сообщение об ошибке, время его использования
Swift 4
DispatchQueue.main.async { //code }
Swift 3
DispatchQueue.main.async(){ //code }
Предыдущие версии Swift
dispatch_async(dispatch_get_main_queue()){ //code }
Ответ 3
Ошибка "это приложение модифицирует механизм автоматической разметки из фонового потока" регистрируется в консоли задолго до того, как возникла реальная проблема, поэтому отладка может быть сложной без использования точки останова.
Я использовал ответ @markussvensson, чтобы обнаружить мою проблему, и нашел ее с помощью этой символической точки останова (Debug> Breakpoints> Create Symbolic Breakpoint):
- Символы:
[UIView layoutIfNeeded]
или [UIView updateConstraintsIfNeeded]
- Условие
!(BOOL)[NSThread isMainThread]
![enter image description here]()
Создайте и запустите приложение на эмуляторе и скопируйте шаги, которые приводят к выдаче сообщения об ошибке (приложение будет работать медленнее, чем обычно!). Затем Xcode остановит приложение и отметит строку кода (например, вызов функции), которая обращается к пользовательскому интерфейсу из фонового потока.
Ответ 4
Когда вы пытаетесь обновить значение текстового поля или добавить подвью внутри фонового потока, вы можете получить эту проблему. По этой причине вы должны поместить этот вид кода в основной поток.
Вам нужно обернуть методы, которые вызывают обновления пользовательского интерфейса с dispatch_asynch, чтобы получить основную очередь. Например:
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.friendLabel.text = "You are following \(friendCount) accounts"
})
EDITED - SWIFT 3:
Теперь мы можем сделать это, следуя следующему коду:
// Move to a background thread to do some long running work
DispatchQueue.global(qos: .userInitiated).async {
// Do long running task here
// Bounce back to the main thread to update the UI
DispatchQueue.main.async {
self.friendLabel.text = "You are following \(friendCount) accounts"
}
}
Ответ 5
Для меня это сообщение об ошибке возникло из баннера из SDK Admob.
Мне удалось проследить происхождение до "WebThread", установив условную точку останова.
![условная точка останова, чтобы найти, кто обновляет ui из фонового потока]()
Затем я смог избавиться от проблемы, инкапсулируя создание баннера с помощью:
dispatch_async(dispatch_get_main_queue(), ^{
_bannerForTableFooter = [[GADBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];
...
}
Я не знаю, почему это помогло, поскольку я не вижу, как этот код вызывается из не основного потока.
Надеюсь, это может помочь кому угодно.
Ответ 6
У меня была эта проблема с момента обновления до IOS 9 SDK, когда я вызывал блок, который обновлял UI в обработчике завершения запроса асинхронного запроса NSURLConnection. Посылка вызова блока в dispatch_async с помощью dispatch_main_queue решила проблему.
Он отлично работал в iOS 8.
Ответ 7
Была та же проблема, потому что я использовал performSelectorInBackground
.
Ответ 8
Вы не должны изменять пользовательский интерфейс вне основного потока! UIKit не является потокобезопасным, так что проблема выше, а также некоторые другие странные проблемы возникнут, если вы это сделаете. Приложение может даже сбой.
Итак, чтобы выполнить операции UIKit, вам нужно определить блок и разрешить его выполнение в главной очереди: например,
NSOperationQueue.mainQueue().addOperationWithBlock {
}
Ответ 9
Очевидно, что вы делаете обновление пользовательского интерфейса для обратной линии. Не могу предсказать, где именно, не видя своего кода.
Вот некоторые ситуации: -
вы можете что-то делать в фоновом потоке и не использовать. Будучи в той же функции, этот код легче определить.
DispatchQueue.main.async { // do UI update here }
вызов func, выполняющего вызов веб-запроса в фоновом потоке и его обработчик завершения, вызывающий другие функции, выполняющие обновление ui.
для решения этой проблемы проверьте код, в котором вы обновили пользовательский интерфейс после вызова веб-запроса.
// Do something on background thread
DispatchQueue.global(qos: .userInitiated).async {
// update UI on main thread
DispatchQueue.main.async {
// Updating whole table view
self.myTableview.reloadData()
}
}
Ответ 10
У меня была эта проблема при перезагрузке данных в UITableView. Просто отправьте перезагрузку следующим образом, исправив проблему для меня.
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
Ответ 11
У меня была та же проблема. Оказывается, я использовал UIAlerts
, который нуждался в основной очереди. Но они устарели.
Когда я изменил UIAlerts
на UIAlertController
, у меня больше не было проблемы и не нужно было использовать какой-либо код dispatch_async
. Урок - обратите внимание на предупреждения. Они помогают, даже если вы этого не ожидаете.
Ответ 12
У вас уже есть правильный код ответа от @Mark, но, чтобы поделиться своими выводами:
Проблема в том, что вы запрашиваете изменение в представлении и предполагаете, что это произойдет мгновенно. На самом деле загрузка представления зависит от доступных ресурсов. Если все загружается достаточно быстро и нет задержек, вы ничего не заметите. В сценариях, где есть какая-либо задержка из-за того, что поток процессов занят и т.д., Приложение запускается в ситуацию, когда предполагается, что оно отображает что-то, даже если оно еще не готово. Следовательно, желательно отправить эти запросы в асинхронных очередях, чтобы они выполнялись на основе нагрузки.
Ответ 13
Основная проблема, связанная с тем, что "это приложение модифицирует механизм автоматической разметки из фонового потока", заключается в том, что оно, по-видимому, регистрируется долгое время после возникновения фактической проблемы, что может усложнить поиск и устранение неисправностей.
Мне удалось решить эту проблему, создав три символических контрольных точки.
Отладка> Точки останова> Создать символическую точку останова...
Точка останова 1:
Точка останова 2:
Точка останова 3:
С помощью этих точек останова вы можете легко получить разрыв в реальной строке, где вы неправильно вызываете методы пользовательского интерфейса в неосновном потоке.
Ответ 14
У меня была эта проблема, когда я использовал TouchID, если это помогает кому-либо еще, обернуть вашу логику успеха, которая, вероятно, что-то сделает с пользовательским интерфейсом в основной очереди.
Ответ 15
Это может быть нечто такое же простое, как установка текстового поля/метки или добавление подвью внутри фонового потока, что может привести к изменению макета поля. Убедитесь, что все, что вы делаете с интерфейсом, происходит только в основном потоке.
Проверьте эту ссылку: https://forums.developer.apple.com/thread/7399
Ответ 16
У меня была такая же проблема при попытке обновить сообщение об ошибке в UILabel в том же ViewController (для обновления данных при попытке сделать это с обычным кодированием требуется некоторое время). Я использовал DispatchQueue
в Swift 3 Xcode 8, и он работает.
Ответ 17
Если вы хотите отследить эту ошибку, используйте флажок pause on Issues для проверки основного потока. В большинстве случаев это легко исправить, отправив проблемную строку в основную очередь.
![enter image description here]()
Ответ 18
Для меня проблема заключалась в следующем. Убедитесь, что performSegueWithIdentifier:
выполняется в основном потоке:
dispatch_async (dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:@"ViewController" sender:nil];
});
Ответ 19
Swift 4,
Предположим, если вы вызываете некоторый метод, используя операционную очередь
operationQueue.addOperation({
self.searchFavourites()
})
И предположим, что функция searchFavourites похожа,
func searchFavourites() {
DispatchQueue.main.async {
//Your code
}
}
если вы вызываете, весь код внутри метода "searchFavourites" в основном потоке, он все равно будет давать ошибку, если вы обновляете в нем некоторый пользовательский интерфейс.
Это приложение модифицирует механизм автозапуска из фонового потока после того, как движок был доступен из основного потока.
Поэтому используйте решение,
operationQueue.addOperation({
DispatchQueue.main.async {
self.searchFavourites()
}
})
Для этого сценария.
Ответ 20
Я также столкнулся с этой проблемой, увидев тонну этих сообщений и трассировку стека на выходе, когда я изменил размер окна на меньший размер, чем его начальное значение. Проведя долгое время, выяснив проблему, я подумал, что поделюсь довольно простым решением. Я однажды включил возможность Can Draw Concurrently
на NSTextView
через IB. Это говорит AppKit, что он может вызывать метод draw(_:)
из другого потока. После его отключения у меня больше нет сообщений об ошибках. Я не испытывал никаких проблем до обновления до macOS 10.14 Beta, но в то же время я также начал изменять код для выполнения работы с текстовым представлением.
Ответ 21
Вот зацените эту строчку из логов
$S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
вы можете проверить, какую функцию вызывать из фонового потока или где вы вызываете метод API, вам нужно вызывать свою функцию из основного потока следующим образом.
DispatchQueue.main.async { func()}
func() - это та функция, которую вы хотите вызвать в результате вызова API успех или что-то еще.
Журналы здесь
This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
Stack:(
0 Foundation 0x00000001c570ce50 <redacted> + 96
1 Foundation 0x00000001c5501868 <redacted> + 32
2 Foundation 0x00000001c5544370 <redacted> + 540
3 Foundation 0x00000001c5543840 <redacted> + 396
4 Foundation 0x00000001c554358c <redacted> + 272
5 Foundation 0x00000001c5542e10 <redacted> + 264
6 UIKitCore 0x00000001f20d62e4 <redacted> + 488
7 UIKitCore 0x00000001f20d67b0 <redacted> + 36
8 UIKitCore 0x00000001f20d6eb0 <redacted> + 84
9 Foundation 0x00000001c571d124 <redacted> + 76
10 Foundation 0x00000001c54ff30c <redacted> + 108
11 Foundation 0x00000001c54fe304 <redacted> + 328
12 UIKitCore 0x00000001f151dc0c <redacted> + 156
13 UIKitCore 0x00000001f151e0c0 <redacted> + 152
14 UIKitCore 0x00000001f1514834 <redacted> + 868
15 UIKitCore 0x00000001f1518760 <redacted> + 104
16 UIKitCore 0x00000001f1543370 <redacted> + 1772
17 UIKitCore 0x00000001f1546598 <redacted> + 120
18 UIKitCore 0x00000001f14fc850 <redacted> + 1452
19 UIKitCore 0x00000001f168f318 <redacted> + 196
20 UIKitCore 0x00000001f168d330 <redacted> + 144
21 AppName 0x0000000100b8ed00 $S12AppName18ViewControllerC11Func()ySS_S2StF + 4420
22 AppName 0x0000000100b8d9f4 $S12CcfU0_y10Foundation4DataVSg_So13NSURLResponseCSgs5Error_pSgtcfU_ + 2384
23 App NAme 0x0000000100a98f3c $S10Foundation4DataVSgSo13NSURLResponseCSgs5Error_pSgIegggg_So6NSDataCSgAGSo7NSErrorCSgIeyByyy_TR + 316
24 CFNetwork 0x00000001c513aa00 <redacted> + 32
25 CFNetwork 0x00000001c514f1a0 <redacted> + 176
26 Foundation 0x00000001c55ed8bc <redacted> + 16
27 Foundation 0x00000001c54f5ab8 <redacted> + 72
28 Foundation 0x00000001c54f4f8c <redacted> + 740
29 Foundation 0x00000001c55ef790 <redacted> + 272
30 libdispatch.dylib 0x000000010286f824 _dispatch_call_block_and_release + 24
31 libdispatch.dylib 0x0000000102870dc8 _dispatch_client_callout + 16
32 libdispatch.dylib 0x00000001028741c4 _dispatch_continuation_pop + 528
33 libdispatch.dylib 0x0000000102873604 _dispatch_async_redirect_invoke + 632
34 libdispatch.dylib 0x00000001028821dc _dispatch_root_queue_drain + 376
35 libdispatch.dylib 0x0000000102882bc8 _dispatch_worker_thread2 + 156
36 libsystem_pthread.dylib 0x00000001c477917c _pthread_wqthread + 472
37 libsystem_pthread.dylib 0x00000001c477bcec start_wqthread + 4
)