Получение "Это приложение изменяет ошибку автозапуска из фонового потока"?

Очень часто сталкивалась с этой ошибкой в ​​моей ОС 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):

  1. Символы: [UIView layoutIfNeeded] или [UIView updateConstraintsIfNeeded]
  2. Условие !(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:

  • Символ: -[UIView setNeedsLayout]

  • Состояние: !(BOOL)[NSThread isMainThread]

Точка останова 2:

  • Символ: -[UIView layoutIfNeeded]

  • Состояние: !(BOOL)[NSThread isMainThread]

Точка останова 3:

  • Символ: -[UIView updateConstraintsIfNeeded]

  • Состояние: !(BOOL)[NSThread isMainThread]

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

Ответ 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
)