Swift: If let statement failing to handle empty array
我有一个使用 Foursquare API 下载 JSON 数据的应用程序。我正在使用 NSURLSession 和带有完成块方法的 dataTaskWithRequest 来获取数据。我得到的数据很好,但有时名为 groups 的嵌套数组可能为空。当我像下面这样解析 JSON 时,由于某种原因,我的条件语句没有像我期望的那样处理空数组。而不是将数组评估为空并继续执行 if let…else 语句的”else”部分,而是通过运行时错误声明:index 0 beyond bounds of empty array
1
2 3 4 5 6 7 8 9 10 11 12 13 14 |
if let response: NSDictionary = data[“response”] as? [String: AnyObject],
groups: NSArray = response[“groups”] as? NSArray, // Error here \\|/ (sometimes groups array is empty) dic: NSDictionary = groups[0] as? NSDictionary, items: NSArray = dic[“items”] as! NSArray { } else { // Never gets here. Why? |
我对 Swift 比较陌生,谁能告诉我为什么会发生这种情况以及我能做些什么来解决这个问题?谢谢
- 你试过 nsnull 检查数组响应对象的值吗?
- 意思是实际测试类类型 NSNull?
- 我知道我可以做这样的事情,我只是想在这里理解 Swift。在我看来,如果它是空的(意思是假的)它会这样评估。当 if 语句通常这样做时,它们会掉到 else 块中。我想我在这里对 Swift 的 if let 有点困惑。
- 好吧,你可以试试这个,这是来自 Matt(IOS 标签上的顶部海报):或 card:AnyObject in arr { switch card { // 如何测试不同的可能类型 case let card as NSNull: // 做一个thing case let card as Card: // 做不同的事情 default: fatalError(“unexpected object in card array”) // 永远不会发生! } } stackoverflow.com/questions/24026609/…
- 我总是 NSNull 检查,但是 vadian,在他的答案下面可能也有你的答案,这与该值为 null 或 vadian 发布的内容有关,它也发生在 Obj C 中,而不仅仅是 swift
如果数组为空,则必须在 if let 语句之外显式检查,因为
空数组永远不是可选的
1
2 3 4 5 6 7 8 9 |
if let response = data[“response”] as? [String: AnyObject], groups = response[“groups”] as? NSArray {
if !groups.isEmpty { if let dic = groups[0] as? NSDictionary { items = dic[“items”] as! NSArray // do something with items println(items) } } } else … |
向下转换类型时可以省略所有类型注释
但是,您可以使用 where 子句执行检查,这适用于 Swift 1.2 和 2
1
2 3 4 5 6 7 |
if let response = data[“response”] as? [String: AnyObject],
groups = response[“groups”] as? [AnyObject] where !groups.isEmpty, let dic = groups[0] as? NSDictionary, items = dic[“items”] as? NSArray { // do something with items println(items) } else {… |
- 我认为这是我必须要做的,并且已经这样做了。我只是想凭借 Swift 的强大功能,if let 的预期目的实际上可以解决我的情况。感谢您的回答。
在尝试访问之前确保数组不为空:
1
2 3 4 5 6 7 8 9 10 11 |
if let response: NSDictionary = data[“response”] as? [String: AnyObject],
let groups: NSArray = response[“groups”] as? NSArray where groups.count > 0 { if let dic: NSDictionary = groups[0] as? NSDictionary, let items: NSArray = dic[“items”] as? NSArray { // Do something.. return // When the 2nd if fails, we never hit the else clause } } // Do logic for else here |
在语句之间使用 && 运算符。
例如这不会崩溃:
1
2 3 4 5 6 7 |
var a = 4;
var c = 5; var array = Array<Int>(); if a > 2 && c > 10 && array[0] != 0 { } |
来源:https://www.codenong.com/32283954/