从类型 (_,_,_) throws -> Void 到非抛出函数类型 (NSData?, NSURLResponse?, NSError?) -> Void 的无效转换

Posted

技术标签:

【中文标题】从类型 (_,_,_) throws -> Void 到非抛出函数类型 (NSData?, NSURLResponse?, NSError?) -> Void 的无效转换【英文标题】:Invalid conversion from throwing function of type (_,_,_) throws -> Void to non-throwing function type (NSData?, NSURLResponse?, NSError?) -> Void 【发布时间】:2015-12-24 08:35:47 【问题描述】:

我已经写了这段代码:

func getjson() 
        let urlPath = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
        let url = NSURL(string: urlPath)
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithURL(url!, completionHandler: data, response, error -> Void in
            print("Task completed")
            if(error != nil) 
                print(error!.localizedDescription)
            
            let err: NSError?
            if let jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary 
                if(err != nil) 
                    print("JSON Error \(err!.localizedDescription)")
                
                if let results: NSArray = jsonResult["results"] as? NSArray 
                    dispatch_async(dispatch_get_main_queue(), 
                        self.tableData = results
                        self.Indextableview.reloadData()
                    )
                
            
        )

        task.resume()

    

更新到 XCode 7 后,它给了我这个错误:从 (_, _, _) 类型的抛出函数抛出的无效转换 -> Void 到非抛出函数类型 (NSData?, NSURLResponse?, NSError?) - > 无效。排队了,让任务在哪里。

谢谢

【问题讨论】:

指出导致问题的行并使用完整准确的错误消息更新您的问题。 但是我应该在哪里使用try? @LeoDabus 在尝试添加成功后应该运行的代码后进行尝试 我已经更新了完整的错误消息@rmaddy 尝试代码已在非 try-catch 块中使用。它发生在我身上。通过将 try xxx 更改为 try? xxx 来修复它 【参考方案1】:

您需要按如下方式实现 Do Try Catch 错误处理:

import UIKit
import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true

extension URL 
    func asyncDownload(completion: @escaping (_ data: Data?, _ response: URLResponse?, _ error: Error?) -> ()) 
        URLSession.shared
            .dataTask(with: self, completionHandler: completion)
            .resume()
    


let jsonURL = URL(string: "https://api.whitehouse.gov/v1/petitions.json?limit=100")!
let start = Date()
jsonURL.asyncDownload  data, response, error in

    print("Download ended:", Date().description(with: .current))
    print("Elapsed Time:", Date().timeIntervalSince(start), terminator: " seconds\n")
    print("Data size:", data?.count ?? "nil", terminator: " bytes\n\n")

    guard let data = data else 
        print("URLSession dataTask error:", error ?? "nil")
        return
    

    do 
        let jsonObject = try JSONSerialization.jsonObject(with: data)
        if let dictionary = jsonObject as? [String: Any],
            let results = dictionary["results"] as? [[String: Any]] 
            DispatchQueue.main.async 
                results.forEach  print($0["body"] ?? "", terminator: "\n\n") 
      //        self.tableData = results
      //        self.Indextableview.reloadData()
            
        
     catch 
        print("JSONSerialization error:", error)
    

print("\nDownload started:", start.description(with: .current))

【讨论】:

有没有办法让错误更上一层楼?因为我的“getjson”函数在一个单独的类中。而且我不想打印错误描述,而是在 UIAlertController 中向用户显示它。但是 UIAlertController 只能通过调用“getjson”函数的 UIViewController 显示。 @Adarkas2302 是一种异步方法,实现此目的的最简单方法是发布通知并将观察者添加到您需要显示警报的视图控制器。 ***.com/a/30541063/2303865【参考方案2】:

正如 Leo 所建议的,您的问题是您使用的是 try,但不在 do-try-catch 构造中,这意味着它推断出闭包被定义为抛出错误,但由于它没有这样定义,你会得到那个错误。

所以,添加do-try-catch:

func getjson() 
    let urlPath = "https://api.whitehouse.gov/v1/petitions.json?limit=100"
    let url = URL(string: urlPath)!
    let session = URLSession.shared
    let task = session.dataTask(with: url)  data, response, error in
        print("Task completed")

        guard let data = data, error == nil else 
            print(error?.localizedDescription)
            return
        

        do 
            if let jsonResult = try JSONSerialization.jsonObject(with: data) as? [String: Any] 
                if let results = jsonResult["results"] as? [Any] 
                    DispatchQueue.main.async 
                        self.tableData = results
                        self.indexTableView.reloadData()
                    
                
            
         catch let parseError 
            print("JSON Error \(parseError.localizedDescription)")
        
    

    task.resume()

【讨论】:

【参考方案3】:

在 Swift 2 中,将所有 NSError 替换为 ErrorType

试试这个。

  class func fetchWeatherForLocation(locationCode: String = "", shouldShowHUD: Bool = false, completionHandler: (data: NSDictionary?, error: ErrorType?) -> ()) 



    let url = NSURL(string: "myurl")               
    let task =  NSURLSession.sharedSession().dataTaskWithURL(url!) (data, response, error) in

        if let dataWithKey = data 

            do 
                let jsonForDataWithTemprature = try NSJSONSerialization.JSONObjectWithData(dataWithKey, options:NSJSONReadingOptions.MutableContainers)

                guard let arrayForDataWithKey :NSArray = jsonForDataWithTemprature as? NSArray else 
                    print("Not a Dictionary")
                    return
                

                let dictionaryWithTemprature = arrayForDataWithKey.firstObject as! NSDictionary

                completionHandler(data: dictionaryWithTemprature, error: nil)

            
            catch let JSONError as ErrorType 
                print("\(JSONError)")
            

        
    

    task.resume()

【讨论】:

【参考方案4】:

更改代码 try-catch 中的错误类型对我有用。

"将所有 NSError 替换为 ErrorType"

【讨论】:

以上是关于从类型 (_,_,_) throws -> Void 到非抛出函数类型 (NSData?, NSURLResponse?, NSError?) -> Void 的无效转换的主要内容,如果未能解决你的问题,请参考以下文章

libQt5Core.so:未定义引用`__cxa_throw_bad_array_new_length@CXXABI_1.3.8

JPA Sql NativeQuery with SqlResultSetMapping throwing java.sql.SQLException: Column 'formula3_0_' no

throws关键字_异常处理的第一种方式(交给别人处理)和try_catch_异常处理的第二种方式(自己处理)

JavaSE01_Day05(中)

在 Xamarin Forms iOS 中启用 AppCenter 崩溃和分析时,本机链接失败,重复符号:“_cxa+throw”

01_6_SERVLET如何从上一个页面取得参数