# Swift Escaping Closures * 當closure作為一個function的argument傳入,但會在function return後被繼續使用的話,就需要在parameter’s type 前面加上 @escaping * 例如 ``` var completionHandlers: [() -> Void] = [] func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) { completionHandlers.append(completionHandler) } ``` * completionHandlers 是一個含 "() -> Void" 的 array * someFunctionWithEscapingClosure 將一個closure做為argument (completionHandler) 傳入,append到completionHandlers中,做為之後使用。 * 因為closure在someFunctionWithEscapingClosure return後還需要被使用,如果沒有加上@escaping, 會發生compile-time error * 當 escaping closure 使用到self是指 class的instance時,需要明確的將self標注出來以表示意圖跟提醒自己避免造成strong reference cycle. 因為該reference會在function return後繼續存活,沒注意的話可能就會有strong reference cycle發生。 * 例如 ``` // 有escaping var completionHandlers: [() -> Void] = [] func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) { completionHandlers.append(completionHandler) } // 沒有escaping func someFunctionWithNonescapingClosure(closure: () -> Void) { closure() } class SomeClass { var x = 10 func doSomething() { someFunctionWithEscapingClosure { self.x = 100 } //有escaping someFunctionWithNonescapingClosure { x = 200 } // 沒有escaping } } let instance = SomeClass() // dosomething 在沒有escaping把x設為200, // 在escaping加入 {()->Void in self.x = 100 } 到completionHandlers中 instance.doSomething() print(instance.x) // Prints "200" completionHandlers.first?() print(instance.x) // Prints "100" // 也可以用capturelist來指稱self: [self] default 是strong class SomeOtherClass { var x = 10 func doSomething() { someFunctionWithEscapingClosure { [self] in x = 100 } someFunctionWithNonescapingClosure { x = 200 } } } // weak 可以避免 strong reference cycle class AnotherClass { var x = 10 func doSomething() { someFunctionWithEscapingClosure { [weak self] in guard let self = self else { return } self.x = 100 } someFunctionWithNonescapingClosure { x = 200 } } } ``` * 如果self is an instance of a structure or an enumeration 就不用特別標示self(coz struct is not a reference),但因為Structures and enumerations don’t allow shared mutability, 在self is an instance of a structure or an enumeration的情況下,escaping closure根本也沒辦法capture a mutable reference to self ``` struct SomeStruct { var x = 10 mutating func doSomething() { someFunctionWithEscapingClosure { x = 100 } // Error someFunctionWithNonescapingClosure { x = 200 } // Ok } } ``` ###### Referece: [swift.org](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/closures#Closure-Expression-Syntax) ###### tags: `Swift`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up