|
| 1 | +--- |
| 2 | +layout: post |
| 3 | +author: matt |
| 4 | +title: "@noescape attribute" |
| 5 | +date: 2015-10-23 17:00:00 +0200 |
| 6 | +comments: false |
| 7 | +categories: |
| 8 | +--- |
| 9 | + |
| 10 | +Swift 1.2 introduced us with `@noescape` attribute. It's a very important feature, when we want to make our code more cleaner and stricter. Using it properly at 3am will prevent many unwanted retain cycles. |
| 11 | + |
| 12 | +While digging into [release notes](https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html) we can see a bunch of clever words: |
| 13 | +> A new `@noescape` attribute may be used on closure parameters to functions. This indicates that the parameter is only ever called (or passed as an @noescape parameter in a call), which means that it cannot outlive the lifetime of the call. This enables some minor performance optimizations, but more importantly disables the `self.` requirement in closure arguments. |
| 14 | +
|
| 15 | +Lets analyze those smart statements and put it into code so everyone can enjoy it: |
| 16 | + |
| 17 | +```swift |
| 18 | +func foo(@noescape code:(() -> String)) -> String |
| 19 | +{ |
| 20 | + return "foo \(bar(code))" |
| 21 | +} |
| 22 | + |
| 23 | +func bar(@noescape code:(() -> String)) -> String |
| 24 | +{ |
| 25 | + return code() |
| 26 | +} |
| 27 | + |
| 28 | +print(foo() {"bar"}) |
| 29 | +``` |
| 30 | + |
| 31 | +It can be also captured in another `@noescape` closure: |
| 32 | + |
| 33 | +```swift |
| 34 | +func baz(@noescape code:(() -> String)) |
| 35 | +{ |
| 36 | + qux { |
| 37 | + code() |
| 38 | + } |
| 39 | +} |
| 40 | +func qux(@noescape code:(() -> String)) {} |
| 41 | +``` |
| 42 | + |
| 43 | +It's important to point out, that closures (and functions) annotated with `@noescape` can only be passed as `@noescape` parameters. What this mean is: |
| 44 | + |
| 45 | +* we cannot run it asynchronously: |
| 46 | +{% img center /images/noescape-attribute/noescape-async.png %} |
| 47 | +* we can't store it |
| 48 | +{% img center /images/noescape-attribute/noescape-store.png %} |
| 49 | +* we can't capture it in another non-`@noescape` closure |
| 50 | +{% img center /images/noescape-attribute/noescape-capture.png %} |
| 51 | + |
| 52 | +Last to mention, in the future releases this will be taken even further: |
| 53 | + |
| 54 | +> This enables control-flow-like functions to be more transparent about their behavior. In a future beta, the standard library will adopt this attribute in functions like autoreleasepool(). |
| 55 | +```swift |
| 56 | +func autoreleasepool(@noescape code: () -> ()) { |
| 57 | + pushAutoreleasePool() |
| 58 | + code() |
| 59 | + popAutoreleasePool() |
| 60 | +} |
| 61 | +``` |
| 62 | +So dear developer the best is yet to come! ;] |
0 commit comments