簡短回答:主線程。更具體地講:
- 更新在主線程中的數據模型
在主線程
- 刷新表視圖數據(實際上,做主線程上的所有 UI的東西,總是)
如果你這樣做,你應該沒有問題。
如果您使用的是類似NSURLConnection
的東西,您可以指定接收數據時應該派發完成過程的隊列(即NSOperationQueue.mainQueue()
)。如果您正在執行的其他任務最終在另一個線程上執行,則可以使用類似performSelectorOnMainThread
或dispatch_async
至dispatch_get_main_queue
的方式將其發送回主線程。
您可以重裝只是特定部分(通過reloadSections:withRowAnimation:
),或者甚至只是某些行(reloadRowsAtIndexPaths:withRowAnimation:
),但我不會有任何的打擾,除非/直到有一個問題(例如,降低性能或閃爍因過度重繪)。只需重新加載整個表格,直到您發現您需要做其他事情。
我知道你說你不是在尋找一個代碼示例,但我只是不能幫助自己;我的代碼溝通比言語更好。
主要事情是tableView:cellForRowAtIndexPath:
,它發出一個URL請求(通過NSURLConnection
)。完成進程(派發到主隊列)解析一些JSON,更新模型並重新加載表。而已。
class ViewController: UIViewController, UITableViewDataSource {
@IBOutlet weak var tableView: UITableView!
private var appIds = [ "391439366", "549762657", "568903335", "327630330", "281796108", "506003812" ]
private var ratings = [String : Int]() // AppID : RatingCount
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.appIds.count;
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let aCell = UITableViewCell(style: .Value2, reuseIdentifier: "RatingCell")
let appId = appIds[indexPath.row]
aCell.textLabel?.text = appId
if let count = self.ratings[appId] {
// Already got rating count for this app - display it.
aCell.detailTextLabel!.text = String(count)
aCell.accessoryView = nil
}
else {
// Don't have rating count: go get it.
self.getNumberOfRatingsForAppID(appId) {
success, number in
if success {
// Update model and reload table.
self.ratings[appId] = number
self.tableView.reloadData()
}
}
// Progress indicator while we wait for data.
let spinner = UIActivityIndicatorView(activityIndicatorStyle: .Gray)
spinner.startAnimating()
aCell.accessoryView = spinner
}
return aCell
}
typealias GetRatingsCompletion = (Bool, Int) ->()
func getNumberOfRatingsForAppID(appID: String, completion: GetRatingsCompletion) {
let appStoreURL = NSURL(string: "https://itunes.apple.com/lookup?id=\(appID)")
let request = NSURLRequest(URL: appStoreURL!)
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) {
response, data, error in
guard data != nil else {
completion(false, 0)
return
}
if let
jsonResult = (try? NSJSONSerialization.JSONObjectWithData(data!, options:[])) as? NSDictionary,
results = jsonResult["results"] as? NSArray,
result = results[0] as? NSDictionary,
numberOfRatings = result["userRatingCountForCurrentVersion"] as? Int
{
completion(true, numberOfRatings)
return
}
completion(false, 0)
}
}
}
這並沒有試圖回答這個問題。不要將評論發佈爲答案。 – rmaddy
不要掛在「部分」上。它只是3個不同的API請求,它們在表格的三個不同部分顯示數據。是的,我認爲數據源在第一個請求完成更新表之前會被第二個請求更新。這就是爲什麼我提到了一個鎖定隊列系統,但我更關心解決這個問題的正確方法。 – Andrew
@Andrew看到我更新的答案。 – HeavenlyManBR