How do I dispatch functions in Swift the right way?

I’ve kept trying but I just don’t get it. I’m rather new to programming so almost every new step is an experiment. Whereas I have no problems dispatching normal closures without arguments/returns, I haven’t understood so far how to deal with functions that take (multiple) arguments and return in the end.

To get the logic of the proper “work around” it would be great if someone could post a practical example so I could see whether I’ve got all of it right. I’d be very thankful for any kind of help… If some other practical example illustrate the topic in a better way, please go ahead with your own!

  • UITableViewCell needs reloadData() to resize to correct height
  • Change height of inputAccessoryView issue
  • HTTP Long Polling in Swift
  • ios 8 interactive notifications not showing actions
  • How do I hide/show tabBar when tapped using Swift in iOS8
  • Parse.com error 'Method not allowed when Pinning is enabled.' when I use a PFQueryTableViewController subclass
  • Let’s say we’d like to asynchronously dispatch the following function to a background queue with low priority (or do I make the mistake, trying to implement the dispatch when defining a function instead of waiting till it is called from somewhere else?!):

    func mutateInt(someInt: Int) -> Int {
        "someHeavyCalculations"
        return result
    }
    

    or a function with multiple arguments that in addition calls the first function at some point (everything in background queue):

    func someBadExample(someString: String, anotherInt: Int) -> Int {
        "someHeavyStuff"
        println(testString)
        mutateInt(testInt)
        return result
    }
    

    or a UI-function that should be ensured to run just on main queue (just a fictitious example):

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {        
        let sectionInfo = self.fetchedResultsController.sections?[section] as NSFetchedResultsSectionInfo       
        return sectionInfo.numberOfObjects
    }
    

    Solutions Collect From Internet About “How do I dispatch functions in Swift the right way?”

    Let’s say you had some function like so:

    func calculate(foo: String, bar: Int) -> Int {
        // slow calculations performed here
    
        return result
    }
    

    If you wanted to do that asynchronously, you could wrap it in something like this:

    func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) {
        DispatchQueue.global().async {
            // slow calculations performed here
    
            completionHandler(result)
        }
    }
    

    Or, alternatively, if you want to ensure the completion handler is always called on the main queue, you could have this do that for you, too:

    func calculate(foo: String, bar: Int, completionHandler: @escaping (Int) -> Void) {
        DispatchQueue.global().async {
            // slow calculations performed here
    
            DispatchQueue.main.async {           
                completionHandler(result)
            }
        }
    }
    

    For the work being performed in the background, you may use a different priority background queue, or your might use your own custom queue or your own operation queue. But those details aren’t really material to the question at hand.

    What is relevant is that this function, itself, doesn’t return any value even though the underlying synchronous function does. Instead, this asynchronous rendition is passing the value back via the completionHandler closure. Thus, you would use it like so:

    calculate(foo: "life", bar: 42) { result in
        // we can use the `result` here (e.g. update model or UI accordingly)
    
        print("the result is = \(result)")
    }
    
    // but don't try to use `result` here, because we get here immediately, before
    // the above slow, asynchronous process is done
    

    (FYI, all of the above examples are Swift 3. For Swift 2.3 rendition, see previous version of this answer.)