簡體   English   中英

如何在Swift中處理帶尾隨閉包語法的拋出閉包?

[英]How can I handle a throwing closure with trailing closure syntax in Swift?

我正在使用Alamofire來執行HTTP請求。

try Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    let error = response.error;

   if (error != nil) {
     throw MyError(message: "No good")
   }


   // This line is from Alamofire docs and causes no issue 
   let json = try! JSONSerialization.jsonObject(with: response.data!, options: [])

   // do more goodies here which may also throw exceptions
}

由於我添加了throw,我得到錯誤Invalid conversion from throwing function of type '(_) throws -> ()' to non-throwing function type '(DefaultDataResponse) -> Void' 我以前得到過這個,並且知道我只需要在正確的地方添加try 我以為在Alamofire.request面前這樣做可能會Alamofire.request ,但事實並非如此。

我也試過了

let req = Alamofire.request(url, headers: headers).validate();
try req.response { response in

當我搜索“扔在尾隨封閉中”時,我找不到任何關於此的內容。

根據上面的評論,我不能直接拋出。 我最終這樣做了:

try Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    do {
      let error = response.error;

      if (error != nil) {
        throw MyError(message: "No good")
      }

      // more logic

      if (anotherCondition == true) {
        throw AnotherError(message: "Error Parsing return data that I expected");
      }

    }
    catch let error {
      uiMessage = "";
      if error is errorThatUserShouldSeeSomething {
        uiMessage = error.localizedDescription;
      }
      ErrorHandler.handle(error: error, uiMessage: uiMessage); 
    }
}

我老老實實會去做ErrorHandler.handle調用,無論如何這都是我的自定義處理程序。 盡管如此,讓它在堆棧中更高一點會更好。

問題是你傳遞給Alamofire的關閉是不允許扔的。 如果你問自己“如果這個函數丟了誰會處理它?”這是有道理的。 拋出你調用函數的范圍是行不通的(也就是在Alamofire.request添加一個try ),因為在異步操作之后將調用閉包,你可能完全離開了作用域。 如果Alamofire在你的關閉周圍有一個do-catch阻擋,這將打敗你允許你扔在第一位的目的,因為Alamofire不知道如何處理你扔的錯誤,只需要吃掉它(沒用)或通過某種關閉或通知將其傳回給你,現在我們已經走了一圈。 在這種情況下,我認為解決問題的最佳方法是調用你在catch塊中放置的任何東西來處理你想要的Alamofire.request拋出錯誤。

Alamofire.request(url, headers: headers)
  .validate()
  .response { response in
    let error = response.error;

   if (error != nil) {
     DaveSteinErrorHandler.handleError(MyError(message: "No good"))
   }


   // This line is from Alamofire docs and causes no issue 
   let json = try! JSONSerialization.jsonObject(with: response.data!, options: [])

   // do more goodies here
}

為了將來參考,在這種情況下,有一些術語和代碼用於定義您編寫的代碼正在執行的行為。 rethrows關鍵字意味着您正在調用的函數將接受閉包作為參數,並且函數將拋出的唯一錯誤是來自您的拋出閉包的錯誤。

您應該遵循do-try-catch語法。

所以,你應該做更像這樣的事情:

do {
    try Alamofire.request(url, headers: headers)
    /* Rest of the try */
} catch {
    /* Runs if the `try` fails
}

該錯誤非常具有誤導性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM