我想用服务器数据更新tableview。
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
var aedList = [AED]()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(animated: Bool) {
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.aedList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in
self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
dispatch_async(dispatch_get_main_queue(), { () -> Void in
cell.textLabel?.text = self.aedList[indexPath.row].street
self.tableView.reloadData()
})
}
return cell
}
正在正确下载数据,但tableview为空。
我想这是由于我下载的异步行为,numberOfRows
方法尝试计算一个仍为空的数组。
如何更正此值以正确显示数据?我是否还需要在那里使用dispatch_async?
答案 0 :(得分:2)
cellForRowAtIndexPath作为方法名称暗示,它由每个单元格的表视图调用,因此您不应该在那里获取整个数据,它用于单独填充单元格。以下是代码中的一些修复:
class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView: UITableView!
var aedList = [AED]()
//In addition to viewDidLoad, you can call this method whenever you wanna update your table
func fetchData() {
Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in
self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
dispatch_async(dispatch_get_main_queue()) { [weak self] in
self?.tableView.reloadData()
}
})
}
override func viewDidLoad() {
super.viewDidLoad()
fetchData()
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return aedList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
cell.textLabel?.text = self.aedList[indexPath.row].street
return cell
}
答案 1 :(得分:1)
从tableView:cellForRowAtIndexPath:
加载数据永远不会有效。为每个单元调用此方法,这意味着:
如果没有单元格(数据尚未加载),则永远不会调用该方法,也不会加载您的数据(现在正在发生这种情况)。
如果数据已加载,您将为每个显示的单元格触发新的加载,也就是说,如果您有5个项目,则会触发5次加载。这是递归的,因为reloadData
将重新显示所有单元格。
解决方案:
将您的加载代码放到更好的位置,例如控制器的viewDidAppear
方法。
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
Server().getJsonInformationFromServer(url: "aeds") { (response) -> Void in
self.aedList = JSONHelper().parseAEDInformation(json: response["data"])
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.tableView.reloadData()
})
}
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath)
cell.textLabel?.text = self.aedList[indexPath.row].street
return cell
}