Objective C- Trouble updating UI on main thread
dispatch_async(dispatch_get_global_queue(0, 0), ^{
//load your data here.
dispatch_async(dispatch_get_main_queue(), ^{
//update UI in main thread.
});
});
How to push a UI update to the mean thread in Objective-C
The error message is telling you that the UI must be updated on the main thread.
You simply need to push the update method updateTimerLabel to the main thread:
dispatch_async(dispatch_get_main_queue(), ^{
[self->_timerLabel setIntValue:[self->_test counter]];
});
Let me know if this helps.
UI not updating even though updates are called from main thread
Most likely you have your format statement wrong.
label.text = [NSString stringWithFormat:@"%f", someTimeDependentValue];
Make sure that someTimeDependentValue is a float. If it is an int it will likely get formatted to 0.0000.
Here's a repo showing a working version of what you describe. Whatever is wrong is not related to the threading.
Objective-c how to update UI depending on background process
You must update the UI on the main thread. To do so, you should call dispatch_async(dispatch_get_main_queue())
when you detect that the wifi was connected/disconnected and then update your image accordingly. Like so:
reach.reachableBlock = ^(Reachability*reach)
{
dispatch_async(dispatch_get_main_queue(), ^{
connectivity = true;
NSLog(@"REACHABLE!");
[yourImage setImage:[UIImage imageNamed:@"withWifi"]];
});
};
reach.unreachableBlock = ^(Reachability*reach)
{
dispatch_async(dispatch_get_main_queue(), ^{
connectivity = false;
NSLog(@"UNREACHABLE!");
[yourImage setImage:[UIImage imageNamed:@"noWifi"]];
});
};
How to update UI from thread
Update your code with the code mentioned below and reason for not updating your UI has already been mentioned in answer above:
You dispatch onto the main thread at the start of your code and then enter an infinite loop, so the main thread runloop will never run again.
Run your threads for appending string in the background and update your UI on the main thread.
- (void)viewDidLoad {
[super viewDidLoad];
_output=[NSMutableString string];
_lineLock=[[NSLock alloc] init];
_line=[NSMutableString string];
_myQueue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Thread
do {
dispatch_async(_myQueue, ^{
if([_lineLock tryLock]) {
[self append:'A'];
[_lineLock unlock];
}
});
dispatch_async(_myQueue, ^{
if([_lineLock tryLock]) {
[self append:'B'];
[_lineLock unlock];
}
});
} while (true);
});
}
iOS - When To Call UI Changing Functions In The Main Thread
Short answer: Yes you should update your UI on main thread.
Threads and Your User Interface
If your application has a graphical user interface, it is recommended
that you receive user-related events and initiate interface updates
from your application’s main thread. This approach helps avoid
synchronization issues associated with handling user events and
drawing window content. Some frameworks, such as Cocoa, generally
require this behavior, but even for those that do not, keeping this
behavior on the main thread has the advantage of simplifying the logic
for managing your user interface.There are a few notable exceptions where it is advantageous to perform
graphical operations from other threads. For example, you can use
secondary threads to create and process images and perform other
image-related calculations. Using secondary threads for these
operations can greatly increase performance. If you are not sure about
a particular graphical operation though, plan on doing it from your
main thread.
Reference:
https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/AboutThreads/AboutThreads.html
UI not updating in main thread
It could be a nil
problem, however, you provide too little info to know for sure. The reason it works with dispatch_async
and doesn't without is not necessarily the thread you're calling the methods from, it could be that, at the time when you call the code, some of your UI objects are nil. When you call dispatch_async
you add the job to the queue but since all dispatch queues are first-in, first-out data structures, you actually add the job at the end of the run loop, which potentially gives time for initialisation (wherever that is done)
Related Topics
iOS 11 - Unable to Change Navigation Bar Height
How Can One Enable Keyboard Like in Imessages/Fb Messenger in Landscape Mode at iOS8
Gcd - Main VS Background Thread for Updating a Uiimageview
Game Engine Collison Bitmask... Why 0X01 etc
Sprite Kit Sprites Loading Performance Improvement
How to Hide "Back to Safari" from Status Bar in iOS9
Avplayerviewcontroller Using Audio-Only Avplayer
Why Is -Force_Load No Longer Required for My Three20 Dependencies in Xcode 4.2
How to Add Navigation Interface After Create a Tab Bar Controller Programmatically (Swift)
Synchronizing Read/Write Access to an Instance Variable for High Performance in iOS
How to Take Uiimage of Avcapturevideopreviewlayer Instead of Avcapturephotooutput Capture
Grouping Coredata by Date() in Swiftui List as Sections
How to Emulate Nfc Cards in iOS 13
How to Properly Send an Image to Cloudkit as Ckasset
Taking Photo with Custom Camera Swift 3