swift - 如何修复错误:线程 1:致命错误:索引超出范围”?
问题描述
url 从内容视图传递到第二个视图。然后将来自网站的 csv 内容传递到一个数组中。当我在其中输入 print(html2) 时,func path(in rect: CGRect) -> Path {
它会在控制台中打印整个数组。
但是我只想要数组的特定部分。如您所见,我想将这些值添加到路径中。但是当我尝试只从数组中获取一个值(并将其转换为 Double)时,我得到错误“线程 1:致命错误:索引超出范围”我不明白为什么会发生这种情况,因为整个数组长于 3。
编辑: NIL 也打印在控制台中(来自guard let url = url else { return ["Nil"] }
,也许这与它有关。
控制台中的打印数组如下所示:
["日期 (M/D/YYYY),时间 (H:MM:SS),地心天顶角", "137.953123", "137.960600", "135.198176", "130.197954", "123.688949", "116.325934", " 108.624973“,“ 101.000252”,“ 93.815722”,“ 87.217417”,“ 82.082535”,“ 78.352650”,“ 78.352650”,“ 76.383830”,“ 76.35635”,“ 76.35635”,“ , "108.374905", "116.056945", "123.404211", "129.901657", "134.897752"]
这是我的代码:
func loadData(from url: URL?) -> Array<String> {
guard let url = url else {
return ["Nil"]
}
let html = try! String(contentsOf: url, encoding: String.Encoding.utf8)
let parsedCSV: [String] = html.components(
separatedBy: "00:00,"
).map{ $0.components(separatedBy: "\n")[0] }
return parsedCSV
}
struct elevationFunction: Shape {
var url1: URL?
var html2: Array<String> { loadData(from: self.url1) }
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 10, y: (125 - (90-Double(html2[3])!)))) // the error is here
path.addLine(to: CGPoint(x: 120, y: (125 - (90-45))))
path.addLine(to: CGPoint(x: 250, y: (125 - (90-Double(html2[3])!)))) // and here
var scale = (rect.height / 350) * (9/10)
var xOffset = (rect.width / 6)
var yOffset = (rect.height / 6.5)
return path.applying(CGAffineTransform(scaleX: scale, y: scale)).applying(CGAffineTransform(translationX: xOffset, y: yOffset))
}
}
解决方案
数组索引从零开始,第三个元素是索引 2
path.move(to: CGPoint(x: 10, y: (125 - (90-Double(html2[2])!))))
path.addLine(to: CGPoint(x: 120, y: (125 - (90-45))))
path.addLine(to: CGPoint(x: 250, y: (125 - (90-Double(html2[2])!))))
我有一个似曾相识的感觉:我记得这段代码,我记得曾鼓励您使用URLSession
CSV 数据并将其解析为结构。
在操场上运行它
struct Zenith {
let date : Date
let angle : Double
}
func loadData(from urlString: String, completion: @escaping (Result<[Zenith],Error>) -> Void) {
guard let url = URL(string: urlString) else {
completion( .failure(URLError(.badURL))); return
}
let task = URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error { completion(.failure(error)); return }
let formatter = DateFormatter()
formatter.locale = Locale (identifier: "en_US_POSIX")
formatter.dateFormat = "M/d/yyyy H:mm:ss"
let csvLines = String(data: data!, encoding: .utf8)!.components(separatedBy: .newlines).dropFirst()
let zenithData = csvLines.compactMap { line -> Zenith? in
let components = line.components(separatedBy: ",")
guard components.count == 3 else { return nil }
guard let date = formatter.date(from: components[0] + " " + components[1]),
let angle = Double(components[2]) else { return nil }
return Zenith(date: date, angle: angle)
}
completion(.success(zenithData))
}
task.resume()
}
let urlString = "https://midcdmz.nrel.gov/apps/spa.pl?syear=2020&smonth=2&sday=1&eyear=2020&emonth=2&eday=1&otype=0&step=60&stepunit=1&hr=12&min=0&sec=0&latitude=59&longitude=10.757933&timezone=1.0&elev=53&press=835&temp=10&dut1=0.0&deltat=64.797&azmrot=180&slope=0&refract=0.5667&field=0"
loadData(from: urlString) { result in
switch result {
case .success(let data): print(data)
case .failure(let error): print(error)
}
}
如果您异步加载数据,则无论如何都必须删除loadData()
调用。Shape
推荐阅读
- visual-studio-code - 如何创建提示窗口以显示 gif 并在几秒钟后关闭窗口?
- angular - 启用内容编码:gzip 用于 angular(7) Web 应用程序中的生产构建?
- svelte - 如何在 Svelte 中设置事件的全局样式
- sql - 在一行中查询多个事务
- android - 类的协程单元测试失败
- typescript - 带有 *ngFor 的 ng-template 问题在 Angular 8
- c++ - 如何计算字符串并将其存储在变量中?
- java - 程序切片插件 Indus 和 kaveri 在 eclipse 中是如何工作的?
- php - 在 CodeIgniter 文件上传中设置最大大小
- html - 如何在 widget::Nav items YII2 中修改 UL 标签的默认属性