从类型 (_,_,_) 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_异常处理的第二种方式(自己处理)
在 Xamarin Forms iOS 中启用 AppCenter 崩溃和分析时,本机链接失败,重复符号:“_cxa+throw”