2015-11-06 3 views
1

Я просто разбираюсь в разработке iOS и Xcode в целом, и я изучаю его с помощью Swift 2. Я пытаюсь получить некоторые данные JSON от URL, разделить его на быстрый Array и отобразить его в TableView. Мне удалось разбить данные JSON на Array, но мне трудно перезагрузить данные таблицы, чтобы отобразить это. Вот код, у меня есть:Данные Swift 2 не перезагружают данные при изменении массива строк

// 
// ViewController.swift 
// Table JSON 
// 
// Created by James Allison on 06/11/2015. 
// Copyright © 2015 James Allison. All rights reserved. 
// 

import UIKit 

class ViewController: UIViewController { 

    var cellContent = ["this should be replaced","something","something else"] 

    @IBOutlet weak var table: UITableView! 
    override func viewDidLoad() { 
     super.viewDidLoad() 

     // construct url 
     let url = NSURL(string: "http://127.0.0.1:8888/json.php")! 

     let task = NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) -> Void in 
      // the following will happen when the task is complete 
      if let urlContent = data { 

       var webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding) 

       // remove [] 
       webContent = webContent?.stringByReplacingOccurrencesOfString("[", withString: "") 
       webContent = webContent?.stringByReplacingOccurrencesOfString("]", withString: "") 

       // split by commas 
       var webContentArr = webContent?.componentsSeparatedByString(",") 

       var temp = "" 
       // remove quote marks 
       for var i = 0; i < webContentArr!.count; i++ { 
        temp = webContentArr![i] 
        temp = temp.stringByReplacingOccurrencesOfString("\"", withString: "") 
        webContentArr![i] = temp 
       } 

       print(webContentArr!) 
       self.cellContent = webContentArr! as! Array 
       self.table.reloadData() 

      } 
      else { 
       // something failed 
       print("Error: invalid URL or something.") 
      } 
     } 
     task.resume() 

    } 

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return cellContent.count 
    } 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 
     cell.textLabel?.text = cellContent[indexPath.row] 

     return cell 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 


} 

В тот момент, когда я запускаю это таблица отображает исходную cellContent переменную, но не новый. Ошибок не возникает, и массив печатается в порядке.

Редактировать: Спасибо Joshua за ваш ответ. Я в конечном итоге, используя следующий код, чтобы решить мою проблему:

dispatch_async(dispatch_get_main_queue(), {() -> Void in 
    self.cellContent = webContentArr! as! Array 
    self.table.reloadData() 
}) 

ответ

1

В догадке, ваш «будет тогда, когда задача будет завершена» код выполняется на какой-нить/очереди, кроме основной, который не играет ну с обновлениями пользовательского интерфейса. Все, что касается пользовательского интерфейса , должно быть выполнено в главной очереди.

Вы должны скорректировать свой код так, чтобы как замена cellContent, так и вызов в виде таблицы на reloadData() запланированы в основной очереди после того, как вы закончили обработку всего. Для этого, завернуть как вышеуказанные вызовы в асинхронной отправки посланного в основную очередь:

dispatch_async(dispatch_get_main_queue(), ^{ 

    self.cellContent = webContentArr! as! Array 
    self.table.reloadData() 

}); 

Это гарантирует, что cellContent массив не модифицируются «за спиной табличного представления» в то время как это обновив UI в главной очереди (плохой!) И что представление таблицы не пытается обновить снова, пока оно не будет выполнено с любыми текущими обновлениями.

Надеюсь, это поможет.

+0

Thanks Joshua, ранее не знал о потоках и очередях. – James

+0

Добро пожаловать. :-) Это очень важная тема, о которой нужно знать, особенно при взаимодействии с любыми объектами пользовательского интерфейса. Каждый раз, когда вы передаете закрытие (блок кода, который запускается позже), который должен обновлять пользовательский интерфейс при его запуске, не забудьте «вернуться назад» в основную очередь, чтобы обновить любые коллекции (например, ваш массив 'cellContent') или другой свойств, которые требуется пользовательскому интерфейсу, и для обновления самого пользовательского интерфейса. –

Смежные вопросы