One awesome plus is that by using the @noescape attribute, the compiler will further optimize your non-escaping code actually give you compiler optimizations for your code as well.

Another awesome plus is that within the body of a non escaping closure, you don't need to explicitly capture self, weakly or otherwise. Since the non-escaping closure will be executed or torn down by the end of the function that it's a parameter of, there is no need to mess with capture semantics for that closure. This allows for awesome code that looks like this:

class Kraken {} class KrakenGeneral { var soldiers = [Kraken]() func startTheWar() { prepareTheKrakenArmyForBattle(punishments: { soldiers.removeFirst() //notice that we don't need self here. }) } func prepareTheKrakenArmyForBattle(@noescape punishments punishments: () -> Void) { if someoneReportedMisbehavior { //Someone was misbehaving. Helping out the humans. We can't have that now. punishments() } } }

Back to Top

@autoclosure

@autoclosure is another Swift attribute that you may have seen but can't figure out what it does. It's pretty similar to the @noescape attribute. First, it can only be applied to closure parameters, and the use of @autoclosure automatically applies @noescape for that closure parameter.

The @autoclosure attribute delays the execution of a function that's activated in a function parameter. Essentially, calling a function inside of a parameter will wrap the function call in a closure for later use in the function body. For example, you may see a lot of code that does this:

krakenGeneral.punishSoldier(soldiers.removeFirst()) func punishSoldier(soldier: Kraken) { throwSoldierInTheBrig(soldier) sendSoldierHomeToMommy(soldier) }

Here, as soon as the krakenGeneral calls the punishSoldier() function, the removeFirst() function gets called. This immediately removes the first object in the soldiers array and returns that object to be passed in to the soldier parameter. Then, you do what you will with the offending kraken soldier. But what if you don't want the first soldier to be removed until later? What if you're a compassionate Kraken Officer? What if you want to give the poor guy a chance before sending him home to his mommy?

Enter @autoclosure .

Because @autoclosure wraps the passed in parameter in a closure, we can put off the removal of the soldier until we deem best in the body of the punishSoldier() function like so:

//The removeFirst() function won't get called here. punishSoldier(soldiers.removeFirst()) //@autoclosure can only be used on closure types. Let's match our parameter to the removeFirst() function type. func punishSoldier(@autoclosure soldierPunishment: () -> Kraken) { //Now we can decide when to remove our soldier. if someoneReportedMisbehavior { //This will remove the soldier and send that soldier home. sendSoldierHomeToMommy(soldierPunishment()) } else { apologizeToSoldierAndFeedHimAHuman() } }

At a high level, the above code is equivalent to this:

punishSoldier { soldiers.removeFirst() } func punishSoldier(@noescape soldierPunishment: () -> Kraken) { if someoneReportedMisbehavior { //This will remove the soldier and send that soldier home. sendSoldierHomeToMommy(soldierPunishment()) } else { apologizeToSoldierAndFeedHimAHuman() } }

The main difference in syntax is at the call site. The @autoclosure attribute isn't used often, because the use of it can make your code a bit unreadable. In our first example, if we didn't know the contents of our punishSoldier() function, we could still assume that the first object of our soldiers array has been removed. Because of @autoclosure , it hides the implementation of our closure parameter. Hiding implementations are almost never a good thing. Personally, I would suggest against using it unless it makes sense what is happening.

Previously, I mentioned that using @autoclosure automatically turns the closure parameter into a non-escaping closure. If you really want the closure to escape for whatever reason, you can apply an additional attribute to @autoclosure like so:

var storageForAClosure: (() -> Bool)? func executeFunctionWithEscapableClosure(@autoclosure(escaping) houdiniClosure: () -> Bool) { storageForAClosure = houdiniClosure } executeFunctionWithEscapableClosure("kraken".hasPrefix("k")) storageForAClosure?() //hasPrefix doesn't execute until this line of code

By putting the keyword escaping inside of parentheses to the right of the @autoclosure attribute, you are telling the compiler that the closure parameter is an escaping closure.

Back to Top

Inline Lazy Vars

This may not be new to you all, but either way, I feel this deserves a spot on the Hipster Swift board. I'm sure we all know what a lazy variable is. In case you don't, it's essentially an instance variable that is initialized only once throughout the lifetime of an object, and returns its one-time-initialization value everytime you access it. This is useful for computationally-intensive values or when a property's value isn't known until after the the object it belongs to is created. For the most part, we create lazy variables like this:

class KrakenFoodGenerator { lazy var lazyHuman: Human = { //We want a lazy human. Kraken's get annoyed //when they have to chase their food. return self.generateWithOptions(.Lazy) }() }

Swift makes lazy initialization very easy but I get kind of annoyed when I have to put a lazy variable in my variable list and it takes up so much space. Awesomely enough, the good Humans over on the Swift team thought of this for us. We can inline our lazy vars and reduce the above code to one line:

class KrakenFoodGenerator { lazy var lazyHuman: Human = self.generateWithOptions(.Lazy) }

But wait, that's weird...we're using self in the variable declaration! What kind of self is it? Will it give us a retain cycle? Lazy vars are just closures after all. How come I can use self here but not when the lazy keyword is applied?!

Well, I can't really tell you how that's possible. However, after writing the autoclosure section above, I can make a very good guess. It seems as though anything after the equals sign of a lazy variable is automatically wrapped in a closure for us. As for the use of self, it does capture it strongly. However, you shouldn't run into a retain cycle and here's the proof: