a432511
a432511

Reputation: 1905

iOS GCD Thread Processing - View Controller Dismissed

Consider the following code in a ViewController which runs when the user clicks a button:

var myBlock = {
    [weak self] in
    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)
    dispatch_async(queue) {
        // Some heavy lifting code with final UI Feedback
        let success = true
        if(success) {
            if let strongSelf = self {
                dispatch_async(dispatch_get_main_queue(), { () -> Void in
                    // Tell user it was successful
                    strongSelf.label1.text = "SUCCESS!"
                });
            }
        }
    });
}

In the area where the heavy lifting occurs, lets say there is a process that takes about 5-10 seconds. If during that period the user dismisses the ViewController in which this code resides, does the background thread continue to run? If so, when the success block runs and attempts to access the UI element on the UI thread, what happens?

Ultimately, I am trying to understand the best practice for queueing a process in the background that updates the UI when possible. Also, if the user presses the home button, this process MUST continue in the background to completion. I have read that you can add: UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler() Is that meant to operate inside a thread as seen above?

I'm sure this is a bit of a noob question, but I could really use some best practice guidance here.

Thanks!

Upvotes: 0

Views: 349

Answers (1)

Dario
Dario

Reputation: 3135

When you reference to self inside a block a strong reference is stored in order to keep the reference until it is executed. The best practice is to create a weak self version to avoid retain cycles. You can achieve this creating the weak version outside the block like so in Objective C:

__weak typeof(self) weakSelf = self;

And in Swift:

var myBlock = {
[weak self] in
//some work with self
}

and access weakSelf instead of self in the block.

You can learn a little bit more in the next link.

The background thread will continue to run, you can implement NSOperations if you need to be a cancelable task. If you can unwrap the optional inside the block you can update the UI.

About beginBackgroundTaskWithExpirationHandler, it is used to mark the beginning of a long task you are about to start and get an extra time to complete it (and notify when it is done) in case the App is backgrounded, but if it can't be performed in that time the app will be terminated. You can use it if you needed, but it will not ensure to have the time to done your task.

Upvotes: 1

Related Questions