![](/img/trans.png)
[英]Xcode 10 Swift build error: “Converting non-escaping value to 'T' may allow it to escape”
[英]Swift 3 :Closure use of non-escaping parameter may allow it to escape
我有以下功能,我有完成處理程序,但我收到此錯誤:
Closure use of non-escaping parameter may allow it to escape
這是我的代碼:
func makeRequestcompletion(completion:(_ response:Data, _ error:NSError)->Void) {
let urlString = URL(string: "http://someUrl.com")
if let url = urlString {
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, urlRequestResponse, error) in
completion(data, error) // <-- here is I'm getting the error
})
task.resume()
}
}
我真的很感謝你的幫助
看起來你需要明確定義允許閉包轉義。
當閉包作為參數傳遞給函數時,閉包被稱為轉義函數,但在函數返回后調用。 當您聲明一個以閉包作為其參數之一的函數時,您可以在參數的類型之前編寫@escaping以指示允許閉包轉義。
TLDR; 在完成變量后添加@escaping
關鍵字:
func makeRequestcompletion(completion: @escaping (_ response:Data, _ error:NSError)->Void) {
let urlString = URL(string: "http://someUrl.com")
if let url = urlString {
let task = URLSession.shared.dataTask(with: url, completionHandler: { (data, urlRequestResponse, error) in
completion(data, error) // <-- here is I'm getting the error
})
task.resume()
}
}
“轉義”閉包是一個閉包,它可以比它創建的范圍更長。轉出閉包需要特別注意引用計數和內存管理,並且可能更難以優化。
在Swift 3之前,閉包的默認設置是假設它們正在轉義。 這意味着開發人員必須專門識別已知不會被轉義的閉包,以允許編譯器進行優化。 社區發現事實上,編譯器可以很容易地找出閉包是否轉出,並決定一種積極的轉義方法可以導致更快的代碼。 結果是現在假定閉包是非轉義的,並且您需要標記使用@escaping
屬性轉義的閉包。
在您的情況下, URLSession.shared.dataTask
接受的閉包本身就是一個轉義閉包,因此如果您在其中使用閉包,則還需要將其標記為@escaping
。
@escaping
對所有調用方法都具有感染力,編譯器確定何時必須包含它。
考慮這個例子(編譯):
dispatchSometime( { print("Oh yeah") })
func dispatchSometime(_ block: ()->()) {
dispatchNow(block)
}
func dispatchNow(_ block: ()->()) {
block()
}
但是,此修改示例會產生兩個類型non-escaping parameter may allow it to escape
錯誤, non-escaping parameter may allow it to escape
:
dispatchSometime( { print("Oh yeah") })
func dispatchSometime(_ block: ()->()) {
dispatchLater(block)
}
func dispatchLater(_ block: ()->()) {
DispatchQueue.main.async(execute: block)
}
main上的dispatchLater
意味着dispatchLater
方法需要@escaping
,一旦你添加了它, dispatchSometime
方法也需要@escaping
來編譯示例。
dispatchSometime( { print("Oh yeah") })
func dispatchSometime(_ block: @escaping ()->()) {
dispatchLater(block)
}
func dispatchLater(_ block: @escaping ()->()) {
DispatchQueue.main.async(execute: block)
}
然而,帶走只是:
@escaping
,直到編譯器停止抱怨。 weak
捕獲變量,因為它們可能與塊本身一起保留。” 啟示
這個真正有趣的情況是你需要調整幾個方法來包含@escaping
關鍵字,這@escaping
編譯器停止抱怨。 但是,如果這些方法實際上符合協議,則該協議的方法還必須獲取@escaping
關鍵字,該關鍵字也會感染所有其他協議符合性。 有趣!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.