numberOfRowsInSection在Alamofire连接之前被调用。
问题的原因是,在Alamofire.request
方法内部的闭包中,当从服务器获取到数据后,会更新self.answerArray
,然后调用self.tableView.reloadData()
方法来刷新表格。但是,在调用reloadData()
方法之前,numberOfRowsInSection
方法已经被UITableView
的代理调用了,此时self.answerArray
还没有被更新,所以表格显示的数据不正确。
解决方法是,在获取数据后,先更新self.answerArray
,然后再调用self.tableView.reloadData()
方法来刷新表格。这样,在numberOfRowsInSection
方法被调用时,self.answerArray
已经被正确地更新了,表格显示的数据就会正确。
修改后的代码如下:
Alamofire.request(.POST, "http://localhost:3000/api/v1/questions/question_detail",parameters: parameters, encoding: .JSON)
.responseJSON { (request, response, JSON, error) in
println(JSON!)
// Make models from JSON data
self.answerArray = (JSON!["answers"] as? NSMutableArray)!
self.tableView.reloadData()
}
这样,当从服务器获取到数据后,先更新self.answerArray
,然后调用self.tableView.reloadData()
方法来刷新表格,保证表格显示的数据是正确的。
问题原因:在Alamofire连接之前调用了numberOfRowsInSection方法。
解决方法:将self.tableView.reloadData()移动到didSet回调中。
我认为更优雅的方法是每次将answerArray赋值时重新加载tableView,这样每当从API获取到响应时,tableView就会自动更新。
将self.tableView.reloadData()移动到didSet回调中。
var answerArray = NSMutableArray() {
didSet {
self.tableView.reloadData()
}
}
这个方法非常好。我认为这是's代码中的一个bug。不过这个技巧非常聪明。使用这种方法,原来的self.tableView.reloadData()应该完全消失。
是的,这是正确的(+1)。但值得注意的是,这种方法有点脆弱,因为它的正确操作取决于responseJSON完成处理程序闭包的实现细节。如果该闭包没有替换answerArray,而是只是删除旧对象并添加新对象,那么这种方法将无效。对于可变对象,应该谨慎使用didSet,因为它仅检测对象是否被完全替换,而不检测对象内部的更改。此外,在MVC世界中,模型对象真的不应该更新视图对象。