1

I'm running a series of dispatches, and when the final one is finished, I want to change the label of a button. Changing swift, however, doesn't like when UI component changes are made outside of the main thread. Sometimes it works. Sometimes it doesn't. And strangely, when it doesn't, if I click the breakpoint icon (regardless of if I'm activating all breakpoints, or disabling, the label immediately changes as desired.

    @IBAction func runButtonSelected(sender: AnyObject) {
        runButton.setTitle("Stop Run", forState: UIControlState.Normal)
        isRunning = true
        self.run()
    }

.

    func run() {
    let thread = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

    NSThread.sleepForTimeInterval(1)
    dispatch_async(thread, {
        NSThread.sleepForTimeInterval(1)
        .           
        .
        .
        .       
        var request = Request(URL: NSURL(string: url+params)!, method: "GET", params: "")
        request.isRequesting = true
        queue.addOperation(request)
        request.threadPriority = 0
        request.completionBlock = {() -> () in
            request.execute()
            NSThread.sleepForTimeInterval(2)
        }
        while request.isRequesting {
            if !request.isRequesting {
                break
            }
        }

        .
        .
        .
        .           
        /* visit user profiles based on match results */
        for (index, profile) in profiles.enumerate() {
            let URL = NSURL(string: "https://www.somewebsite.com/profile/\(profile)")!
            let request = Request(URL: URL, method: "GET", params: "")

            var contentsOfURL = NSString()
            request.isRequesting = true
            queue.addOperation(request)
            request.threadPriority = 0
            request.completionBlock = {() -> () in
                request.execute()   
            }
            NSThread.sleepForTimeInterval(1)
        }

        self.isRunning = false
    })
    let thread2 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
    dispatch_async(thread2, {
        while self.isRunning {
            if !self.isRunning {
                break
            }
        }
        self.runButton.setTitle("Run", forState: UIControlState.Normal)
    })
}

Request.execute

func execute() {
    let session = NSURLSession.sharedSession()
    let request = NSMutableURLRequest(URL: URL)
    request.HTTPMethod = self.method
    request.HTTPBody = self.params.dataUsingEncoding(NSUTF8StringEncoding)
    self.task = session.dataTaskWithRequest(request) {
        (data, response, error) in
        if error == nil {
            do {
                .
                .
                .
                .                   
                switch self.statusCode {

                case 200:
                    self.contentsOfURL = try NSString(contentsOfURL: self.URL, encoding: NSUTF8StringEncoding)
                case 400:
                    print("400: page not found")

                case 404:
                    print("404: page not found")

                case 407:
                    print("407: failed authenticate proxy credentials")

                default:
                    print("unable to get statusCode")

                }
            } catch {
                print(error)
            }
            self.isRequesting = false
        } else {
            print(error)
        }
    }
        self.task.resume()
}
dbconfession
  • 1,147
  • 2
  • 23
  • 36

1 Answers1

0

Since you want your final dispatch to act on the block after the other dispatches try:

void dispatch_async( dispatch_get_main_queue(), dispatch_block_t block);

This would use the serial dispatch queue associated with the application’s main thread instead of running in the background as your previous one did.

l'L'l
  • 44,951
  • 10
  • 95
  • 146