iOS9 - This application is modifying the autolayout engine from a background thread -- where?
This code PSPDFUIKitMainThreadGuard causes assertions on UIKit access outside the main thread
Steps to use:
- Add to project and compile this file without ARC
- Move
PSPDFAssert
definition to the first of the file - Comment calling of
PSPDFLogError
as it is not defined - import
<UIKit/UIKit.h>
Your app will crash and stop with any attemption to modify any UI element from background thread
For swift use the following code: NBUIKitMainThreadGuard
Xcode7: This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes
I don't know what your code is, but I have an idea as to why this is happening. You must be having some UI changes done in a background thread.
Do not change UI from anything but the main thread, it is bound to
make your application unstable, and crash unpredictably.
Use GCD (Grand Central Dispatch).
You can listen and do work from any thread, and encapsulate UI changes in a dispatch_async:
dispatch_async(dispatch_get_main_queue(), ^{
// Do UI stuff here
});
Getting the following error: This application is modifying the autolayout engine from a background thread
In iOS all UI code must run on the main thread. You are dispatching to a background thread in order to perform your update check, which is fine, but then trying to update the UI from that same background thread, which is causing the error you are seeing. The solution is to add another dispatch_async
inside the first one, wrapping the call to self.showAlertForUpdate()
, but dispatching to the main queue (dispatch_get_main_queue(...
) instead.
This application is modifying the autolayout engine from a background thread - ios9
How else can I reload the table view without getting this error?
You step out to the main thread in order to call reloadData
, like this:
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {
(data, response, error) in
self.jsonResult = try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSMutableArray
dispatch_async(dispatch_get_main_queue()) {
self.tableView.reloadData()
}
}
Always do that any time you touch the interface from code that was called on a background thread. You must never never never never touch the interface except on the main thread.
Getting a This application is modifying the autolayout engine from a background thread error?
It needs to be placed inside a different thread that allows the UI to update as soon as execution of thread function completes:
Modern Swift:
DispatchQueue.main.async {
// Update UI
}
Older versions of Swift, pre Swift 3.
dispatch_async(dispatch_get_main_queue(){
// code here
})
Objective-C:
dispatch_async(dispatch_get_main_queue(), ^{
// code here
});
Downloading from server: This application is modifying the autolayout engine ...
to update UI you should call Main thread
put this code where you updating ui
swift 3 way
DispatchQueue.main.async {
//here you can update UI
}
swift 2 way
dispatch_async(dispatch_get_main_queue()) {
//here you can update UI
}
This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes
Do not change UI from anything but the main thread. While it may appear to work on some OS or devices and not others, it is bound to make your application unstable, and crash unpredictably.
If you must respond to a notification, which can happen in the background, then ensure UIKit
invocation takes place on the main thread.
You at least have these 2 options:
Asynchronous Dispatch
Use GCD
(Grand Central Dispatch) if your observer can be notified on any thread. You can listen and do work from any thread, and encapsulate UI changes in a dispatch_async
:
dispatch_async(dispatch_get_main_queue()) {
// Do UI stuff here
}
When to use GCD
? When you do not control who sends the notification. It can be the OS, a Cocoapod, embedded libraries, etc. Using GCD
will woke anytime, every time. Downside: You find yourself re-scheduling the work.
Listen on Main Thread
Conveniently, you can specify on which thread you want the observer to be notified, at the time you are registering for notifications, using the queue
parameter:
addObserverForName:@"notification"
object:nil
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note){
// Do UI stuff here
}
When to observe on main thread? When you are both registering and registered. Bu the time you respond to the notification, you are already where you need to be.
Post Notification On Main Thread
[self performSelectorOnMainThread:@selector(postNotification:) withObject:notification waitUntilDone:NO];
Hybrid solution which does not guarantee that the observer is only invoked from said method. It allows for lighter observer, at the cost less robust design. Only mentioned here as a solution you should probably avoid.
Related Topics
Set Default iOS Local Notification Style for Application
How to Make a Vertical Text Uilabel and Uitextview for iOS in Swift
Using Uiimagepickercontroller in Landscape Orientation
Application Crashed While Importing Songs from Ipod Library in iPhone for iOS 5.0
Uitextfield Securetextentry Bullets with a Custom Font
Autolayout + Rtl + Uilabel Text Alignment
How to Fill a Uibezierpath with a Gradient
Switch Cameras with Avcapturesession
Uibutton Fails to Properly Register Touch in Bottom Region of iPhone Screen
iPhone Gps in Background Never Resumes After Pause
How to Create Custom Mkannotationview and Custom Annotation Title and Subtitle
When Should I Use the Various Storage Mechanisms in iOS
Uiscreen Mainscreen Bounds Returning Wrong Size
How to Show/Hide a Uibarbuttonitem
Xcode 8 Shows Error That Provisioning Profile Doesn't Include Signing Certificate