0
votes

I'm making a very simple app to practice multi-threading using GCD. I initialized a UIActivityIndicatorView in my ViewController class like so:

class ViewController: UIViewController {

var myActivityIndicator:UIActivityIndicatorView = UIActivityIndicatorView(activityIndicatorStyle: .Gray)

In my viewDidLoad, I added it as a subView to my main view with the following code:

 override func viewDidLoad()
{
    super.viewDidLoad()

    myActivityIndicator.center = view.center
    view.addSubview(myActivityIndicator)
}

Then when my button is tapped, I have an IBAction that handles the event by printing a simple message after a little while. Here is the code for that:

@IBAction func doSomething(sender: AnyObject)
{
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0))
    {
        self.myActivityIndicator.startAnimating()

        sleep(3)

        print("This has been accessed on another thread")

        dispatch_async(dispatch_get_main_queue())
        {
            self.myActivityIndicator.stopAnimating()
        }
    }
}

It seems as though self.myActivityIndicator.startAnimating() isn't getting called, but when I put that line of code in viewDidLoad, it works just fine.

What am I missing?

2
just call myActivityIndicator.startAnimating() from the main queue - Leo Dabus
@LeoDabus Wow that did the trick. I can't believe I overlooked that...thanks! - doc92606

2 Answers

0
votes

This was solved by starting the animation on the main thread:

 @IBAction func doSomething(sender: AnyObject)
{
    self.myActivityIndicator.startAnimating()
...
0
votes

Only the main thread can update UI. So you must put the update UI's action in main thread. Add dispatch_async(dispatch_get_main_queue()) { updateSomeUI(); }

But when in load view controller in viewDidLoad(), it just happened in the main thread, and it can immediately update the UI. When code executed in viewDidLoad() When code executed in buttonClick()

@IBAction func doSomething(sender: AnyObject)
{
    let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(dispatch_get_global_queue(priority, 0))
    {
        dispatch_async(dispatch_get_main_queue()) 
        {
            self.myActivityIndicator.startAnimating()
        }

        sleep(3)

        print("This has been accessed on another thread")

        dispatch_async(dispatch_get_main_queue())
        {
            self.myActivityIndicator.stopAnimating()
        }
    }
}

-Good Luck.