2016-04-07 22 views
1

Üç bölümden oluşan bir tablo görünümü var. Bir parça önceki görünüm denetleyicisinden geçirilir, ancak diğer iki bölümün eşzamansız olarak yüklenmesi gerekir. HTTP yanıtlarını bekleyen alanlarda "yer tutucu yükleme döndürücüleri" görüntülüyorum. Bir bölüm döndüğünde, tablo verilerini güncellemeyi deniyorum, ancak her iki yanıtın da aynı anda döndüğü ve tabloyu aynı anda güncellemeye çalıştığı bir duruma dönüşebileceğimi buluyorum. Tabloyu aynı anda güncellemeye çalışan birden fazla eşzamansız istek nedeniyle çökmemesi için bir çeşit kilit ve sıra uygulamanız gerektiği görülüyor. Ben bilmek istiyorumUITableView'ın birkaç parçasını eşzamansız olarak yükleme ve güncelleştirme

, güvenle/yükleme uyumsuz bir UITableView kısmi bölümünün yenilenmesi için iOS en iyi yöntem budur. Bir kod örneği aramıyorum. Bunun yerine, bunu başarmak için kullanılan terminoloji ve yöntem çağrılarını arıyorum.

cevap

1

Farklı bölümleri (ve bölümlerin statik sayısı) kullanıyorsanız, bunları yeniden yerine tablo görünümünü yeniden deneyin. Bir API döndüğünde, ilgili bölüm güncelleştirin: [self.tableView reloadSections: withRowAnimation:]

+0

Bu soruyu cevaplamak için hiçbir girişimde bulunmaz. Yorumları cevap olarak yayınlamayın. – rmaddy

+0

"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

+0

@Andrew güncellenmiş cevabımı gör. – HeavenlyManBR

1

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) 
     } 
    } 

} 
İlgili konular