У меня есть табличное представление, которое я заполняю результатами http-вызова. Данные передаются в массив с именем tripTimes
. triptimes
содержит информацию об определенных поездках, совершенных в течение данного дня. Время начала каждой поездки в этот день передается в self.tableData
и вставляется в tableView.
После этого перезагружаю таблицу и... странные результаты.
Массив tableData
заполняется правильно, но после того, как я вызываю self.tableView.reloadData()
, почти все ячейки заполняются правильно. Однако первая ячейка остается пустой, пока я не коснусь ее или не подожду около 5 секунд, а последняя ячейка также будет пустой, но через то же время она получит то же значение, что и первая ячейка.
Я думаю, что это должно что-то делать с частью dispatch_async
, но я новичок в Swift и iOS, поэтому понятия не имею, где искать. Когда я печатаю содержимое self.tableData
внутри функции dispatch_async
, массив содержит правильные значения.
Ниже приведен код моего viewController
import UIKit
import Foundation
import SwiftHTTP
class TripSelect: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var dateTextField: UITextField!
@IBOutlet weak var tableView: UITableView!
@IBAction func showTrips(sender: AnyObject) {
//if data is already present in tableData, empty it first
if self.tripTimes.count != 0 && self.tableData.count != 0 {
for var i=0; i<self.tripTimes.count; i++ {
self.tableData.removeObjectAtIndex(0)
let indexPathToRemove = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.deleteRowsAtIndexPaths([indexPathToRemove], withRowAnimation: .Automatic)
}
dispatch_async(dispatch_get_main_queue(), {
self.tableView.reloadData()
})
}
var request = HTTPTask()
request.GET("<MY_URL>", parameters: ["date": dateTextField.text], success: {(response: HTTPResponse) in
if let data = response.responseObject as? NSData {
let str = NSString(data: data, encoding: NSUTF8StringEncoding) as String
let str2 = "\"not enough data for this day\""
if str != str2 {
let json:AnyObject = JSON.parse(str)
self.dayLatLongs = json["dayLatLongs"] as Array
self.tripTimes = json["tripTimes"] as Array
var tripLatLongs:[AnyObject] = self.dayLatLongs[0] as Array
var firstTrip:[AnyObject] = tripLatLongs[0] as Array
var tripStartTime:String = ""
for var i=0; i<self.tripTimes.count; i++ {
tripStartTime = self.tripTimes[i]["startTime"] as String
//println("\(tripStartTime)")
self.tableData.addObject(tripStartTime)
let indexPath = NSIndexPath(forRow: 0, inSection: 0)
self.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)
}
dispatch_async(dispatch_get_main_queue(), {
println(self.tableData)
self.tableView.reloadData()
})
} else {println(str)}
}
},failure: {(error: NSError, response: HTTPResponse?) in
println("error: \(error)")
})
}
var dayLatLongs:[AnyObject] = []
var tripTimes:[AnyObject] = []
var tableData: NSMutableArray! = NSMutableArray()
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell: UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("cell") as UITableViewCell
cell.textLabel?.text = self.tableData.objectAtIndex(indexPath.row) as? String
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
var backgroundView = UIView(frame: CGRectZero)
self.tableView.tableFooterView = backgroundView
self.tableView.backgroundColor = UIColor.clearColor()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ОБНОВИТЬ:
var indexPaths:[NSIndexPath] = [NSIndexPath]()
for var i=0; i<self.tripTimes.count; i++ {
tripStartTime = self.tripTimes[i]["startTime"] as String
self.tableData.addObject(tripStartTime)
indexPaths.append(NSIndexPath(forRow: i, inSection: 0))
}
self.tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .Automatic)
Теперь результаты отображаются правильно, но только после того, как я пару раз "перетащу" таблицу.
success
, скорее всего, все равно работает в основном потоке, поскольку блокshowTrips
, похоже, вызывается в основном потоке. Не нужно использоватьreloadData
послеinsertRowsAtIndexPaths
иdeleteRowsAtIndexPaths
, но нужно убедиться, что ячейки вставляются и удаляются с правильными индексами и только в основном потоке: попробуйте заполнить массив со всеми индексами и сделать одиночную вставку/ удалить вызов, чтобы сделать процесс проще. - person A-Live   schedule 12.02.2015reloadData
будут в основном потоке, сделайте то же самое для вызовов вставки/удаления: они очень похожи наreloadData
в этом смысле и должен всегда вызываться в основном потоке. В этом случае вызовыreloadData
могут быть удалены, так как таблица обновляется автоматически, и вы, вероятно, испортите анимацию. - person A-Live   schedule 12.02.2015