3

我有一個完成處理程序需要分配給屬性,但我希望它異步執行。在調度中包裝完成處理程序的語法async

如果我沒有這個要求,我會寫:

request.completionBlock = completionBlock 

但因爲我有這樣的要求,我必須寫這個

request.completionBlock = { response, error in 
    DispatchQueue.main.async { 
    completionBlock(response, error) 
    } 
} 

這似乎是多餘的和未SWIFTY 。

是不是有一些更簡單的語法?我想寫點類似於

request.completionBlock = completionBlock.map(DispatchQueue.main.async) 

我可以用這麼簡單的方式表達我的需求嗎?

+0

是'request'一個類型的實例,你可以改變,還是需要成爲一個擴展/它的子類? – DavidA

回答

3

沒有用於表達的內置語法,但您可以始終定義一個通用函數或運算符,以便沿這些行啓用某些內容。

例如:

infix operator > 

func ><T>(left:@escaping (T)->(), right:DispatchQueue) -> (T)->() { 
    return { input in 
    right.async { left(input) } 
    } 
} 

隨着定義上述運營商定製,你的代碼可以是:

request.completionBlock = completionBlock > DispatchQueue.main 

我認爲這是一般的感覺,你正在尋找。

+0

我剛剛正好建議用另一種方式來制定它:)謝謝! – KPM

+1

用' - >'我有一個語法錯誤。只用'>'(或'§',或其他什麼,一切都看起來很好)。所以我更新了答案。 – KPM

+0

而實際上我們不需要MultiplicationPrecedence。這甚至是不受歡迎的,原因有兩個:1 /我們不希望具有關聯性,因爲寫入block KPM

0

您是否擁有request類的控制權?如果不是,那麼我認爲你必須咬緊牙關,明確地調度自己(顯然是好的,或者至少在python :-)),或者像丹尼爾霍爾所說的那樣定義你自己的速記。

如果你確實有控制權,那麼我認爲建議你簡單地改變你的request類的API,以保證完成處理程序在主線程中被調用。畢竟處理程序應該是快速的,畢竟,這通常是你想要的。

3

這裏是一個擴展

extension DispatchQueue { 
    func asyncClosure<T>(_ closure:@escaping (T) -> Void) -> (T) -> Void { 
     return {i in self.async {closure(i)}} 
    } 
} 

,可以讓你做到這一點:

request.completionBlock = DispatchQueue.main.asyncClosure(completionBlock) 
+0

這個答案也非常有用。我在你和丹尼爾霍爾之間猶豫了很久。最後,我選擇將獎金授予丹尼爾。非常感謝替代品! – KPM