首页 > 解决方案 > Swift 5:为什么我的结构中的数据突然为空/无?

问题描述

更新:

我想知道的主要事情是,我能够self.schedule (.monday)在成功下载 JSON 函数后登录,但nil在应该刷新表时立即获取。

小小的 Xcode 窗口还显示 <code>schedule</code> 为 <code>nil</code>。

问题

我的当前有两个单独的 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": [
    ...
  ]
}

标签: iosswiftuitableviewstructurlsession

解决方案


你从来没有分配任何东西给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


推荐阅读