Swift 尝试更新将返回的do catch块中的变量:致命错误:在展开可选值时意外发现nil
我想返回类型Swift 尝试更新将返回的do catch块中的变量:致命错误:在展开可选值时意外发现nil,swift,alamofire,Swift,Alamofire,我想返回类型wData(自定义类型)中的currDatacurrData在函数开头声明,并将在do catch块中设置: func getWData(stnID: Int) -> wData{ var currData: wData? let parameters: Parameters = ["id": String(stnID), "accesstype": "w"] Alamofire.request("https://myurl.tld", parameter
wData
(自定义类型)中的currData
currData
在函数开头声明,并将在do catch
块中设置:
func getWData(stnID: Int) -> wData{
var currData: wData?
let parameters: Parameters = ["id": String(stnID), "accesstype": "w"]
Alamofire.request("https://myurl.tld", parameters: parameters).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.data)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
let dArr = utf8Text.components(separatedBy: "~")
do {
try currData = wData(hash: Int(dArr[0])!, stnName: String(dArr[1])!)
} catch {
print("error creating wData Object: \(error)")
}
}
}
return currData!
}
但是,当我尝试返回currData
对象时,会收到以下错误消息:
致命错误:在展开可选值时意外发现nil
我的wData
类如下所示:
class wData{
var hash: Int
var stnName: String
init(hash: Int, stnName: String) {
self.hash = hash
self.stnName = stnName
}
}
我想我可以在我的类中创建一个静态变量:
class wData{
static var currDObj: wData?
var hash: Int
var stnName: String
init(hash: Int, stnName: String) {
self.hash = hash
self.stnName = stnName
currDObj = self
}
}
然后在我的getWData函数中返回currDObj,并使用:
return weatherData.currData!
但它仍然给了我一个错误。我做错了哪一点?这一行
在返回currData之前,很可能不会对currData=wData(hash:Int(dArr[0])、stnName:String(dArr[1])!
进行求值代码>因此currData仍然为零。您需要在函数中使用闭包,而不是返回值
类似这样的情况:(也提高了零安全性)
dArr[0]和dArr[1]的值是多少?您不能从进行异步调用的函数返回值。虽然我同意它会因为异步而失败,但如果尝试失败,它是否也会失败…导致currData为零并崩溃?@rmaddy我不是OP:)。但我指的是OP的原始代码。你可以在你的reply@Honey然后你应该对问题发表评论,而不是这个答案。在您删除您的评论并正确发布后,我将删除我的评论。@rmaddy对我的内存不足表示歉意。实际上我指的是答案的第一行。他说在
返回之前不会对try
进行评估。我试图指出/询问另一个缺陷,我认为他忽略了这一点,在他的解释中,从技术上讲,闭包中的代码有可能在包含函数完成之前运行,但是的,这是它可能中断的另一个地方,这就是我在回答中修复它的原因。但它几乎肯定会在返回声明时崩溃
func getWData(stnID: Int, completion: (wData?) -> ()) {
let parameters: Parameters = ["id": String(stnID), "accesstype": "w"]
Alamofire.request("https://myurl.tld", parameters: parameters).response { response in
print("Request: \(response.request)")
print("Response: \(response.response)")
print("Error: \(response.data)")
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
print("Data: \(utf8Text)")
let dArr = utf8Text.components(separatedBy: "~")
guard let hash = Int(dArr[0]), stnName = String(dArr[1]) else {
completion(nil)
return
}
do {
let currData: wData = try wData(hash: hash, stnName: stnName)
completion(currData)
} catch {
print("error creating wData Object: \(error)")
completion(nil)
}
}
else {
completion(nil)
}
}
}