Fatal error: Index out of range when receive nil data which I marked as optional
Fatal error: Index out of range when receive nil data which I marked as optional
您好,我有一些问题与我的数据模型数组中的索引超出范围有关。只要 images = []
为空,应用程序就会崩溃。
所以这是我的 UIViewController 的 table 视图中的代码。
if let urlString = vehicleList?._embedded.userVehicles[indexPath.row].images[0] {
let url = URL(string: urlString)
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
} else {
let url = URL(string: "https://vehicleimage-insure.s3-eu-west-1.amazonaws.com/defaultCarIcon.png")
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
}
这是我的图像数据模型 属性,我已将其标记为可选:
struct UserVehicles: Codable {
let id: String
let images: [String?]
let userId: String
}
错误信息如下图:
我查看了调试输出,如下:
我的意思是我写了if let语法,难道不应该捕获错误吗?请给我一些提示,我该如何解决这个错误?
if let 语句将检查可选语句是否为 nil。
当您尝试在不存在的索引处访问数组元素时,它不会 return nil 但您会收到索引超出范围错误。
如果你想安全地访问数组中的元素,你应该在访问索引之前执行数组大小检查。
if list.count > 0 {
let listItem = list[0]
// do something
}
或者为 Collection 实现安全访问的扩展。
extension Collection {
/// Returns the element at the specified index if it is within bounds, otherwise nil.
/// Sample: `list[safe: index]`
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
然后你可以使用 if let ,因为这个下标 return 是可选的。
if let listItem = list[safe: 0] {
// do something
}
让我们考虑一下所有可能出错的地方:
if let urlString = vehicleList?._embedded.userVehicles[indexPath.row].images[0]
嗯,vehicleList
可能是 nil
。但这没问题; if let
负责处理。
接下来,您有一个数组引用 userVehicles[indexPath.row]
。好吧,我想数组中可能没有那么多对象。
最后,您得到了另一个数组引用,images[0]
。但是数组可能是空的。
所以我们可以安全地检查所有这些:
if let vList = vehicleList, // avoid `nil`
vList._embedded.userVehicles.count > indexPath.row,
vList._embedded.userVehicles[indexPath.row].images.count > 0 {
// now it is safe
let urlString = vlist._embedded.userVehicles[indexPath.row].images[0]
let url = URL(string: urlString)
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
} else {
// use placeholder URL
}
(如果您的某些对象本身可能 nil
,您可能需要改进该代码,但您已经知道如何做到这一点。)
您好,我有一些问题与我的数据模型数组中的索引超出范围有关。只要 images = []
为空,应用程序就会崩溃。
所以这是我的 UIViewController 的 table 视图中的代码。
if let urlString = vehicleList?._embedded.userVehicles[indexPath.row].images[0] {
let url = URL(string: urlString)
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
} else {
let url = URL(string: "https://vehicleimage-insure.s3-eu-west-1.amazonaws.com/defaultCarIcon.png")
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
}
这是我的图像数据模型 属性,我已将其标记为可选:
struct UserVehicles: Codable {
let id: String
let images: [String?]
let userId: String
}
错误信息如下图:
我查看了调试输出,如下:
我的意思是我写了if let语法,难道不应该捕获错误吗?请给我一些提示,我该如何解决这个错误?
if let 语句将检查可选语句是否为 nil。
当您尝试在不存在的索引处访问数组元素时,它不会 return nil 但您会收到索引超出范围错误。
如果你想安全地访问数组中的元素,你应该在访问索引之前执行数组大小检查。
if list.count > 0 {
let listItem = list[0]
// do something
}
或者为 Collection 实现安全访问的扩展。
extension Collection {
/// Returns the element at the specified index if it is within bounds, otherwise nil.
/// Sample: `list[safe: index]`
subscript (safe index: Index) -> Element? {
return indices.contains(index) ? self[index] : nil
}
}
然后你可以使用 if let ,因为这个下标 return 是可选的。
if let listItem = list[safe: 0] {
// do something
}
让我们考虑一下所有可能出错的地方:
if let urlString = vehicleList?._embedded.userVehicles[indexPath.row].images[0]
嗯,vehicleList
可能是 nil
。但这没问题; if let
负责处理。
接下来,您有一个数组引用 userVehicles[indexPath.row]
。好吧,我想数组中可能没有那么多对象。
最后,您得到了另一个数组引用,images[0]
。但是数组可能是空的。
所以我们可以安全地检查所有这些:
if let vList = vehicleList, // avoid `nil`
vList._embedded.userVehicles.count > indexPath.row,
vList._embedded.userVehicles[indexPath.row].images.count > 0 {
// now it is safe
let urlString = vlist._embedded.userVehicles[indexPath.row].images[0]
let url = URL(string: urlString)
cell.vehicleImage.kf.setImage(with: url, placeholder: nil)
} else {
// use placeholder URL
}
(如果您的某些对象本身可能 nil
,您可能需要改进该代码,但您已经知道如何做到这一点。)