Kısa yanıt: ana iş parçacığı. Daha spesifik olarak:
- Güncelleme ana iş parçacığı üzerinde veri modeli ana iş parçacığı üzerinde
- yükle tablo görünümü veri (aslında, her zaman, ana iş parçacığı üzerinde tüm UI şeyler yapmak)
Yukarıdakileri yaparsanız, sorun yaşamanız gerekir.
NSURLConnection
gibi bir şey kullanıyorsanız, veri alındığında (NSOperationQueue.mainQueue()
olması gerekir) tamamlanma sürecinin gönderileceği kuyruğu belirtebilirsiniz. Farklı bir iş parçacığı üzerinde çalışmayı biten başka bir şey yapıyorsanız, ana iş parçacığına performSelectorOnMainThread
veya dispatch_async
- dispatch_get_main_queue
gibi bir şeyle geri gönderebilirsiniz.
Sen (reloadSections:withRowAnimation:
aracılığıyla) sadece belirli bölümleri ve hatta sadece belirli satırları (reloadRowsAtIndexPaths:withRowAnimation:
) yeniden yükleyebilirsiniz ama bunların hiçbirini rahatsız olmazdı/sürece bir sorun (örneğin, yavaş performans veya titreşim nedeniyle kurulana kadar aşırı yeniden çizme). Aksi halde yapmanız gerekmedikçe, tablonun tamamını yeniden doldurmaya başlayın.
Kod örneği aramayacağınızı söylediğinizi biliyorum, ancak kendime yardım edemiyorum; Kodda kelimelerden daha iyi iletişim kurarım.
Ana şey (NSURLConnection
yoluyla) bir URL isteği yapar tableView:cellForRowAtIndexPath:
olduğunu. Tamamlama proc (ana sıraya gönderilir), bazı JSON'u ayrıştırır, modeli günceller ve tabloyu yeniden yükler. Bu kadar.
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)
}
}
}
Bu soruyu cevaplamak için hiçbir girişimde bulunmaz. Yorumları cevap olarak yayınlamayın. – rmaddy
"Bölümler" e asılma. Bu, tablonun üç farklı bölümünde verileri görüntüleyen sadece 3 farklı API isteği. Evet, veri kaynağının ilk isteği tabloyu güncellemeyi bitirmeden önce ikinci istek tarafından güncelleştirildiğini düşünüyorum. Bu yüzden bir kilitleme ve kuyruk sisteminden bahsetmiştim, ancak bu problemi çözmek için doğru yaklaşımı daha çok merak ediyorum. – Andrew
@Andrew güncellenmiş cevabımı gör. – HeavenlyManBR