Ios 在展开可选值时意外发现nil,但存在一些值

Ios 在展开可选值时意外发现nil,但存在一些值,ios,swift,uitableview,optional,Ios,Swift,Uitableview,Optional,我正在尝试执行get请求,并将以下结果从保存到NSMutuableArray中。然后,我尝试将获得的以下数据加载到tableview中,但每当我尝试配置行数时,都会得到一个“在展开可选值时意外发现为零” var dataArray:NSMutableArray? Alamofire.request(.GET, "SOMERANDOMWEBSITE") .responseJSON { response in // using if-let syntax to save json

我正在尝试执行get请求,并将以下结果从保存到NSMutuableArray中。然后,我尝试将获得的以下数据加载到tableview中,但每当我尝试配置行数时,都会得到一个“在展开可选值时意外发现为零”

var dataArray:NSMutableArray?

Alamofire.request(.GET, "SOMERANDOMWEBSITE") .responseJSON { response in
        // using if-let syntax to save json into our NSMutuableArray
        if let JSON = response.result.value {
            self.dataArray = JSON as? NSMutableArray
        }
    }
当我尝试配置行数时:

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows

    return self.dataArray.count
}
它给了我一个错误:“在展开可选值时意外地发现了nil”。但奇怪的是,当我创建一个随机按钮来查看.count是否确实为零时:

    @IBAction func function(sender: AnyObject) {
    print(self.dataArray?.count)
}

它返回可选的(2)而不是nil。有什么想法吗?

您将阵列设置为可选阵列。我们可以在这里看到:

print(self.dataArray?.count)
因此,在Alamofire的闭包中填充它之前(网络请求发生在后台),它是零

你引用:

return self.dataArray.count
但实际上你可能已经做到了

return self.dataArray!.count
这就是它崩溃的原因

因此,当count为nil时,您必须声明另一个count选项。解决方案可以是安全地展开阵列,然后返回计数或返回默认值:

if let array = self.dataArray {
    return array.count
}
return 0
正如@brian nickel在评论中指出的那样,同样的逻辑可以用一行来表达:

return self.dataArray?.count ?? 0

另外,正如@vadian在评论中所说的,当然,可选数组在这里没有什么意义,最好从一开始就有一个非可选的空数组。

您将数组设置为可选数组。我们可以在这里看到:

print(self.dataArray?.count)
因此,在Alamofire的闭包中填充它之前(网络请求发生在后台),它是零

你引用:

return self.dataArray.count
但实际上你可能已经做到了

return self.dataArray!.count
这就是它崩溃的原因

因此,当count为nil时,您必须声明另一个count选项。解决方案可以是安全地展开阵列,然后返回计数或返回默认值:

if let array = self.dataArray {
    return array.count
}
return 0
正如@brian nickel在评论中指出的那样,同样的逻辑可以用一行来表达:

return self.dataArray?.count ?? 0

另外,正如@vadian在评论中所说的,当然,可选数组在这里没有什么意义,最好从一开始就有一个非可选的空数组。

这并不奇怪,它是异步的

最初,您将
dataArray
声明为可选(也称为
nil
),但不初始化它

第一次更新表视图的尝试失败(崩溃),因为在
nil
上调用
count
是个坏主意

同时,异步请求方法返回数据并将其分配给
dataArray
,该数组现在有一个(可选)值

这就是为什么在
函数中得到结果的原因

解决方案是将数组声明并初始化为非可选的Swift类型

var dataArray = [AnyObject]()
可能有比
AnyObject

并将返回的数据相应地分配给“更好”类型



基本上,将表视图数据源数组声明为可选是荒谬的,因为表视图总是非可选的。

这并不奇怪,它是异步的

最初,您将
dataArray
声明为可选(也称为
nil
),但不初始化它

第一次更新表视图的尝试失败(崩溃),因为在
nil
上调用
count
是个坏主意

同时,异步请求方法返回数据并将其分配给
dataArray
,该数组现在有一个(可选)值

这就是为什么在
函数中得到结果的原因

解决方案是将数组声明并初始化为非可选的Swift类型

var dataArray = [AnyObject]()
可能有比
AnyObject

并将返回的数据相应地分配给“更好”类型



基本上,将表视图数据源数组声明为可选是荒谬的,因为您的表视图始终是非可选的。

web调用后设置的response.result.value是什么?web调用后设置的response.result.value是什么?类似地,它可以是
返回self.dataArray?.count??0
我在答案中添加了速记选项,这是个好主意。谢谢你的建议。无意冒犯,但是可选的数据源数组是非常糟糕的做法。@vadian绝对是。我也考虑过这一点,我只是把它添加到了答案中,因为提醒OP这一点确实是个好主意。谢谢。我尝试了在count为nil时声明另一个选项的方法,但它总是返回0。然后我尝试从一开始就切换到使用非可选的空数组,但遇到了返回0的相同问题。类似地,它可能是
return self.dataArray?.count??0
我在答案中添加了速记选项,这是个好主意。谢谢你的建议。无意冒犯,但是可选的数据源数组是非常糟糕的做法。@vadian绝对是。我也考虑过这一点,我只是把它添加到了答案中,因为提醒OP这一点确实是个好主意。谢谢。我尝试了在count为nil时声明另一个选项的方法,但它总是返回0。然后我尝试从一开始就切换到使用非可选的空数组,但遇到了返回0的相同问题。