1

I have learnt Swift for a while and I have read the Swift language guide.

https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Closures.html#//apple_ref/doc/uid/TP40014097-CH11-ID94

The concept closure is new to me. I think I can understand how to use it, but where I can use it? what is the benefit of it?

I googled and get the answer When to use closures in swift?

I do not thinks the answer is satisfying. The language guide writes so much about it, I guess it is a very important feature of the language, and maybe it's widely used in the framework.

Could anyone show me more example to show it's power? Thanks a lot.

Community
  • 1
  • 1
Lucas Liu
  • 823
  • 1
  • 10
  • 12
  • It is used almost anywhere. Thats why almost any language has them now. – Sulthan Nov 21 '16 at 07:17
  • I am new to swift, I have used java for years and never got a chance to use closures ( Java 8 added it ) – Lucas Liu Nov 21 '16 at 07:44
  • 1
    You probably did. Closures (or something similar) were always in Java, only with a terrible syntax. Since there was no way to write an individual function, you had to wrap it in an interface and create a class for it. `Comparator` interface is a prime example. See http://stackoverflow.com/a/19785549/669586, that `new Comparator() { ...` is a way to create an unnamed function to compare strings. Real closures just remove the unnecessary class around it. – Sulthan Nov 21 '16 at 08:10
  • Even the new Java syntax is still pretty terrible though. – Sulthan Nov 21 '16 at 08:12

2 Answers2

4

The question might be a little broad, but I will try to recap.

Referring to the Documentation:

Closures are self-contained blocks of functionality that can be passed around and used in your code.

You should use closure(s) when you want to pass a chunk of code as a parameter to a method that you want to execute it asynchronously.

To make it simpler -by giving a real-world example-, imagine that there is a method responsible for scanning the user's photos, so the method should returns an array of photos and another array of videos:

Pesudo-code:

// the method should scan the the user's photos and return them after fetching is finished

// the 'completion' (success) closure should returns two arrays
// what if there is something wrong happened? another closure should returns an error

// for the example purposes they are arrays of strings, the error is also a string
func scanPhotos( completion: @escaping (_ photos: [String], _ videos: [String]) -> (), failure: @escaping (String) -> ()) {
    // imagine that the scanning has been successfully done and you filled the two arrays:

    //if scanningSuccess {
        let fetchedPhotos = [String]()
        let fetchedVideos = [String]()

        completion(fetchedPhotos, fetchedVideos)
    //} else {
        // if something goes wrong
        failure("the error!!")
    //}
}

Calling the method:

scanPhotos(completion: { (photos, videos) in
    // now you can use the fetched photos and videos
}, failure: { error in
    // display an alert -for example- based on the error is saying...
})

Note the the scanning proccess should be executed asynchronously, when it finished, one of the two blocks (success or failure) should be executed.


Some of the popular methods that work with clousres:

AGAIN: it is just a simple usage of the closures; You need to check the documentation for more details.

I hope it helped.

Ahmad F
  • 30,560
  • 17
  • 97
  • 143
1

Closures are a concept you use mainly on asynchronous function calls. (at least I do so)

A good example where Apple uses closures is URLSession:

func downloadTask(with url: URL, completionHandler: @escaping (URL?, URLResponse?, Error?) -> Void) -> URLSessionDownloadTask

This method creates an URLSessionDownloadTask that runs in a background thread. When you call this method, you are passing a closure as completionHandler. This closure is executed, when the task has finished.


There are some other cases, but I haven't used them this much yet, because I love the delegate pattern. I found an article that compares Closures and Delegates in Swift.

Delegates in Swift have a big problem: Unless you are using @objc, you have to implement every method of a protocol, which could lead to lots of unnecessary code and would look confusing. That's why I guess it would be much better to use closures in many cases.

FelixSFD
  • 6,052
  • 10
  • 43
  • 117