When to use closures in swift? [closed]

2019-01-23 08:28发布

问题:

I am been to ios development for few months and eager to implement new things in my programming pattern.

Now i am learning closures and knew little things about its syntax,knew it can be used instead of delegate for callbacks. As well as implemented it in some UIViewAnimation and for sorting.

But really i want to know its uses apart from that.i.e where should we use closures in our basic programming. Like we use delegate when we want to send information from child to parent.. So any explanation or brief example on its actual which can be used in our day to day swift programming would be helpful?

Can anyone tell me how these closure actually computes the value

reversed = sorted(names, { (s1: String, s2: String) -> Bool in return s1 > s2 } )

In these example there is names and closure as an argument to a method..but how does this actually computes ?

Can you please explain how these works when passing closures in this animation code :

UIView.animateWithDuration(duration: NSTimeInterval, 
    animations: (() -> Void)?, 
    completion: ((Bool) -> Void)?)

I really want to know about the flow?

回答1:

The two most used cases are completion blocks and higher order functions in Swift.

Completion blocks: for example, when you have some time consuming task, you want to be notified when that task is finished. You can use closures for that, instead of a delegate (or many other things)

func longAction(completion: () -> ()) {
    for index in veryLargeArray {
        // do something with veryLargeArray, which is extremely time-consuming 
    }
    completion() // notify the caller that the longAction is finished 
}

//Or asynch version
func longAction(completion: () -> ()) {

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {

        for elem in veryLargeArray {
            // do something with veryLargeArray, which is extremely time-consuming
        }
        dispatch_async(dispatch_get_main_queue(), { 
            completion() // notify the caller that the longAction is finished 
        })
    }
}

longAction { print("work done") }

In the example above, when you have a time consuming task, you want to know when the for loop finishes iterating through the very large array. You put the closure { println("work done") } as an input parameter for the function which will be executed after the for loop finishes its work, and print "work done". And what happened is that you gave a function (closure) to longAction and name it to completion, and that function will be executed when you call completion in longAction.

Higher order functions: you can use closures as input parameters for higher order functions, for example:

let array = [1, 2, 3]
let smallerThanTwo = array.filter { $0 < 2 }

With this, you can filter out the numbers that are smaller than 2.

UPDATED About how sorted (probably) works:

So the idea is, that sorted will go through the array, and compare two consecutive elements (i, i + 1) with each other, and swap them, if needed. What does it mean "if needed"? You provided the closure { (s1: String, s2: String) -> Bool in return s1 > s2 }, which will return true if s1 is lexiographically greater than s2. And if that closure returned true, the sorted algorithm will swap those two elements, and countinues this with the next two elements (i + 1, i + 2, if the end of the array is not reached). So basically you have to provide a closure for sorted which will tell "when" to swap to elements.



回答2:

  1. Usually Closures does not has names in contrast to other functions. That means them can be used in every case when you want to pass chunk of code to some function without wrapping that code into named method. Sorting is the most popular example.

  2. Closures can use variables outside of its borders. So called "Capturing Values"



回答3:

A closure is something like:

{ (params) -> returnType in
  statements
}

Here are some reasons why to use it from the Apple doc

  • Inferring parameter and return value types from context
  • Implicit returns from single-expression closures
  • Shorthand argument names
  • Trailing closure syntax