In my application i perform long task in background. So i used Grand Central Dispatch (GCD)
and update the UI in main Queue.
Here is my code
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0), {
// perform long task
//update UI
dispatch_async(dispatch_get_main_queue(), {
self.Label.text = "value changed" // not work
self.collectionView.reloadData() // work properly
})
})
It will work fine. However when i move from my current ViewController
to NextViewController
and again back toViewController
background task is executed but my Label
will not change.
QUESTION: Please help me so i can update my UI when back from another ViewController
NOTE: for moving one ViewController to another the task is perform in main queue.
EDIT : here is a output of @Yuri code
2015-06-08 14:34:19.565 myApp[7726:1481939] before: self:Logic() `self.label:<myApp.ViewController: 0x15947e00>
2015-06-08 14:34:50.925 myApp[7726:1481925] after: self:Logic() self.label:<myApp.ViewController: 0x15947e00>`
Edit2 here is output of @Oyeoj
before: <UILabel: 0x16565c60; frame = (20 56; 104 18); text = 'Back up'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16565eb0>>
after: <UILabel: 0x16565c60; frame = (20 56; 104 18); text = 'value changed'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x16565eb0>>
Updates of UI must be made in main thread, it is likely that your updates in UI will not work..
try this:
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0), {
dispatch_async(dispatch_get_main_queue(), {
println("before: \(self.Label)")
self.collectionView.reloadData()
self.Label.text = "value changed"
self.Label.setNeedsDisplay() // don't forget this line..
println("after: \(self.Label)")
})
})
Edit 1
Okay, i'm down voted can i at least know why? just for my edification, thank you..
From your @edit2 log, it seems that the values of self.Label.text
was updated but your UIViewController was not in control of the main thread..
and i will recommend you to use NSNotificationCenter
to trigger the updates in you ViewController
it'll look like this now:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "methodReceiver:", name:"NotificationIdentifier", object: nil)
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0), {
//long task
dispatch_async(dispatch_get_main_queue(), {
// sends notification to `methodReceiver`
NSNotificationCenter.defaultCenter().postNotificationName("NotificationIdentifier", object: nil)
})
})
@objc func methodReceiver(notification: NSNotification){
dispatch_async(dispatch_get_main_queue(), {
self.collectionView.reloadData()
self.Label.text = "value changed"
self.Label.setNeedsDisplay() // don't forget this line..
})
// in case you want to remove the Observer after notification was delivered
NSNotificationCenter.defaultCenter().removeObserver(self, name: "NotificationIdentifier", object: nil)
}
Hope this have helped you for some reason..
Edit 2
from comment:
this approach is work , but i want to know why my UIViewController is not in controll of main thread
Inside your
dispatch_async(dispatch_get_global_queue(Int(QOS_CLASS_BACKGROUND.value), 0)
your are processing in background (long task) and will not block any main thread activity...
then you changed to AnotherUIViewController
which has UI
updates, now your main thread is in AnotherUIViewController
's control while dispatch_async(dispatch_get_global_queue(
is still in progress, then let's say you go back to UIViewController
then dispatch_async(dispatch_get_main_queue(), {
was fired, BUT tasks inside AnotherUIViewController
was not yet done,
like for example:
[self.navigationController popViewControllerAnimated:YES]; // -> (in objective-C code)
or any other UI updates that is currently in progress will be handled first before UIViewController
takes control of main thread again since all dispatch queues are FIFO..
that's how it works i believe..
for more information about that heres Grand Central Dispatch (GCD) Reference from apple..