ios - Swift 5:为什么我的结构中的数据突然为空/无?
问题描述
更新:
我想知道的主要事情是,我能够self.schedule (.monday)
在成功下载 JSON 函数后登录,但nil
在应该刷新表时立即获取。
问题
我的当前有两个单独的 UITableViews ScheduleViewController
,其中的表应该由其downloadSchedule()
功能的视图控制器使用下载的数据以不同方式填充。
任务成功后URLSession
,接收到的数据将存储在新变量json
中,然后在控制台中打印。一切正常。
现在,当downloadSchedule()
函数完成它的请求并调用下一个重新加载表的函数时,我想计算 的数据numberOfRowsInSection
,但我得到了Thread 1: Fatal error: Unexpectedly found nil while unwrapping an optional value
.
虽然这个变量以前是用下载的数据填充的,但是当我想更新表格时,它现在突然变空了。这怎么可能发生?
代码
我ScheduleViewController
像这样声明我的变量:
var schedule: Schedule?
该downloadSchedule()
函数在以下之后执行viewDidLoad()
:
func downloadSchedule(completed: @escaping () -> Void) {
let url = URL(string: "example.com/meta/schedule")
URLSession.shared.dataTask(with: url!) { data, _, error in
if error == nil {
do {
self.schedule = try JSONDecoder().decode(Schedule.self, from: data!)
DispatchQueue.main.async {
print("executed")
completed()
}
} catch {
print("JSON Error")
}
}
}.resume()
}
downloadSchedule {
self.mondayTableView.reloadData()
self.tuesdayTableView.reloadData()
}
首先更新表的示例:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Return the number of items in the sample data structure.
var count:Int?
if tableView == self.mondayTableView {
count = schedule?.monday.count
}
if tableView == self.tuesdayTableView {
count = schedule?.tuesday.count
}
return count!
}
这些是我的日程安排和日期结构:
// MARK: - Schedule
struct Schedule: Codable {
let monday: [Day]
let tuesday: [Day]
let wednesday: [Day]
let thursday: [Day]
let friday: [Day]
let saturday: [Day]
let sunday: [Day]
let nextmonday: [Day]
let nexttuesday: [Day]
let nextwednesday: [Day]
let nextthursday: [Day]
let nextfriday: [Day]
let nextsaturday: [Day]
let nextsunday: [Day]
let airtimeAPIVersion: String
enum CodingKeys: String, CodingKey {
case monday, tuesday, wednesday, thursday, friday, saturday, sunday, nextmonday, nexttuesday, nextwednesday, nextthursday, nextfriday, nextsaturday, nextsunday
case airtimeAPIVersion = "AIRTIME_API_VERSION"
}
}
// MARK: - Day
struct Day: Codable {
let startTimestamp: String?
let endTimestamp: String?
let name: String?
let dayDescription: String?
let id: Int?
let instanceID: Int?
let instanceDescription: String?
let record: Int?
let url: String?
let imagePath: String?
let starts: String?
let ends: String?
enum CodingKeys: String, CodingKey {
case startTimestamp = "start_timestamp"
case endTimestamp = "end_timestamp"
case name = "name"
case dayDescription = "description"
case id = "id"
case instanceID = "instance_id"
case instanceDescription = "instance_description"
case record = "record"
case url = "url"
case imagePath = "image_path"
case starts = "starts"
case ends = "ends"
}
}
JSON
{
"monday": [
{
"start_timestamp": "2020-06-01 01:35:00",
"end_timestamp": "2020-06-01 01:37:37",
"name": "TEST",
"description": "",
"id": 174,
"instance_id": 950,
"instance_description": "",
"record": 0,
"url": "",
"image_path": "example.com/api/show-logo?id=174",
"starts": "2020-06-01 01:35:00",
"ends": "2020-06-01 01:37:37"
}
],
"tuesday": [
...
]
}
解决方案
你从来没有分配任何东西给self.schedule
这两行:
let json = try JSONDecoder().decode(Schedule.self, from: data!)
print(json)
不要改变self.schedule
. 你需要写
self.schedule = try JSONDecoder().decode(Schedule.self, from: data!)
当你这样做时:JSONDecoder().decode(Schedule.self, from: data!)
这意味着“数据是一堆 JSON 字节,将其解析为 Schedule 值并返回它。”
在那一行Schedule.self
中是我们试图将其解析为的类型——它与self.schedule
推荐阅读
- javascript - jQuery 从*所有*链接标题页中获取结果到一个回调中
- c# - 如何使用 ExcelDataReader.Dataset 从 Excel 工作表中获取命名范围
- haskell - 使用幻像参数强制类型类实例
- java - 集群模式下的 Redis Pfcount
- javascript - 移动相机并在三个js中更新它的orbitControl
- jwt - 如何在 Postman 上打开 JWT 令牌以将声明值之一放在变量上
- bash - Linux:关闭 ssh 会话时结束运行 bash 脚本
- testing - CakePHP3:集成测试中的模拟方法?
- java - eclipse java photon中的INSTALL_PARSE_FAILED_NO_CERTIFICATES
- antd - blur 和 focusIn 的输入验证消息切换