简体   繁体   中英

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM