I am doing one application in which i got one HTML string in background thread. I want to load the webview using that HTML string in background.
If I load that web view on background, the app crashes. I don't want to load webview using main thread because on that i don't want to disturb the main thread. And i did the R&D in internet i got one possibility using GCD.I think that one also involved in main thread. SO please let me know how to update the UI in background.
You can not. UI must always be updated from the main thread. Whatever your reason for not wanting to do it from the main thread, that reason is invalid.
No. You cant update UI in other thread then main.
Related
I am facing the crash
Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
I referred to the crash and added the line self.Indicator.stopAnimating() in my code. It runs fine for one or two tests, and it shows the same crash again.
All the UI handling must be done on the main thread instead of the background thread. That's what the crash says.
So move your UI specific code to DispatchQueue.main.async, i.e.
DispatchQueue.main.async {
self?.Indicator.stopAnimating()
}
That stands for all the UI specific changes. Move them to main thread.
Unrelated: use camel-casing for variable names. It must be indicator instead of Indicator.
I was wondering how someone would load multiple UI elements asynchronously. In my case, I have a UIViewController that has a UISegmentControl. Each segment has different UI aspects to load.
For example seg1 shows one image, seg2 shows and image and some text, etc.
If I load all the UI elements before showing the UIViewController then there is a noticeable lag. So I would want to load seg2...n asynchronously to make the UI feel more responsive.
Would I need to load everything via
DispatchQueue.main.async {
// load UI
}
For each seg I want to load in the background? Or can I load these elements on another thread and not take up the main thread? I know you're not supposed to update the UI on background threads... But will using the main thread still block the UI if I use async code?
You can't make UI changes on a background thread. Nearly all UIKit calls must be made on the main thread. Therefore you're likely out of luck.
Instead what you should do is do the time consuming number-crunching (downloading and parsing data for example) on a background thread and then use DispatchQueue.main.async() to install the data into your views on the main thread once the time consuming work is done.
If it's the UI setup that is introducing the lag and it's not possible to speed it up then you may be out of luck.
On iOS, its well documented that the UI should never be updated from a background thread. Rather the main thread should be the sole interface to update the UI. My Question is why?
Is it because UIControls are not thread safe and hence there is always the possibility of main thread updating the particular control whilst its being tinkered with in a background thread? Is my understanding right?
Thanks
I think it has more to do with keeping the UI responsive, so iOS just prevents you from putting UI stuff in threads that aren't main.
You know you can use dispatch_async(dispatch_get_main_queue(), ) { //change UI here } from within a background thread to send your UI actions to the main thread.
I have a UITextField, which checks a password and then my app loads data from a remote server. While this is happening I would like a progress view to display the progress of the download. My issue is that the UITextField seems to lock up the display until it returns and therefore I cannot update the progress view on the main thread. I also would like an answer without GCD or any other kind of threading as I am using core data and that would probably overcomplicate the app. Is there a way to have the UITextField not lock up the view so that I can update my progressView on the main thread?
If your app is loading data from a remote server, then you will have to use multi-threading(GCD, etc). Otherwise it just locks up the main thread till the download is finished which makes your app unresponsive.
To keep it simple, use GCD to fetch data(raw NSData) and give it to the main thread. Do all your processing on the main thread(core data, etc) as usual.
EDIT: One more thing, it is not the textfield locking up your UI, it is the download. So I don't think you can do anything other than multi-threading to help you here.
A UIViewController takes about half a second to load its contents and appear on screen. How can I make them all load in the background and appear when they're ready?
There is a LazyTableImages sample on the Apple developer site.
It shows how to perform the heavy lifting in a background thread and update the UI on the main thread.
PerformSelectorInBackground:withObject: is a possible solution, although a more modern method would be to use asynchronous blocks. You can run code on the main thread from within these blocks to update the UI Safely.
The Concurrency Programming Guide is a good place to find more information and examples of this.
A Background Thread cant update the UI,you can perform all the processing logic in background thread and call the main thread for UI update
Example to load a tableView with Data ,use the background thread to process everything and load the Data, call [tableView reloadData] using the main thread, see Grand central Dispatching to know how to Work with Threads in IOS..
Hope it Helps
Create a GCD queue to process your work in a background thread (read the docs, because my "create" label and options may not be what you want).
You send it to the queue asynchronously, meaning that the call to dispatch_async will make appropriate arrangements for the block of code you give it to run in another thread and it will then return back to you "immediately."
All the work in the block you give it will be executed on a separate thread. Note, at the end, you do another call, this time with the well know main queue. This arranges for that code to run in the main thread, which is mandatory for any UI work.
Also, you really should read the documentation on GCD and especially blocks, because there are memory and cycle considerations. Good luck.
dispatch_queue_t workQ = dispatch_queue_create("bgWorkQ", 0);
dispatch_async(workQ, ^{
// This code is now running in a background thread.
// Do all your loading here...
// When ready to touch the UI, you must do that in the main thread...
disptach_async(dispatch_get_main_queue(), ^{
// Now, this code is running in the main thread.
// Update your UI...
});
});
dispatch_release(workQ);
The easiest way is to use NSObject's - (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg You just pass it a selector and it will happy in the background and not block your UI. Be aware however that there are rules to background threads.
You shouldn't update your UI from the background thread. And you need to make sure the methods you're calling are thread safe.