在解开可选值时意外地发现了nil,但是有一些价值

时间:2016-01-26 21:03:53

标签: ios swift uitableview optional

我正在尝试执行GET请求,并将以下结果保存到NSMutuableArray中。然后我试图加载我进入tableview的以下数据,但每当我尝试配置行数时,我得到“在展开可选值时意外发现nil”。

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)
}

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

2 个答案:

答案 0 :(得分:3)

您使阵列成为可选。我们可以在这里看到:

print(self.dataArray?.count)

所以,直到它在Alamofire的关闭中填充(网络请求在后台发生),它是零。

你引用:

return self.dataArray.count

但实际上你可能已经完成了

return self.dataArray!.count

这就是崩溃的原因。

因此,当它没有时,您必须声明另一个计数选项。解决方案可以是安全地打开数组,然后返回计数或返回默认值:

if let array = self.dataArray {
    return array.count
}
return 0

同样的逻辑可以用一行表示,如评论中的@ brian-nickel说明:

return self.dataArray?.count ?? 0

另外,正如@vadian在评论中所说的那样,绝对地,一个Optional数组在这里没什么意义,从一开始就有一个非可选的空数组会更好。

答案 1 :(得分:1)

这并不奇怪,它是异步的。

最初,您将dataArray声明为可选(又名nil),但不要将其初始化。

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

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

这就是你在var dataArray = [AnyObject]() 得到结果的原因。

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

AnyObject

可能存在比loginList = ['joe', 'sue', 'hani', 'sophie'] if login in loginList: print('you are in!') else: print('User unknown')

更具体的类型

并相应地分配返回的数据,将结果投射到"更好的"类型。

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