2015-05-21 3 views
0

Я хочу запросить с помощью Parse, чтобы добавить строки в массив. Затем я хочу поместить эти строки в ячейки моего UITableView. Однако каждый раз, когда я запускаю приложение, на моем столе ничего не появляется. Вот мой код, если кто-то может помочь объяснить некоторые из причин, по которой он может не отображатьсяUITableView Swift вопросы

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { 

@IBOutlet weak var tableView: UITableView! 


var friendsArray: [String] = [] 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "cell") 

    var usrname = currentUser?.username 
    var query = PFQuery(className:"Relation") 
    query.whereKey("Sender", equalTo : usrname!) 
    query.findObjectsInBackgroundWithBlock { 
     (objects: [AnyObject]?, error: NSError?) -> Void in 

     if error == nil { 
      // The find succeeded. 
      //println("Successfully retrieved \(objects) scores.") 
      // Do something with the found objects 
      if let objects = objects as? [PFObject] { 
       for object in objects { 
        var friendName = object["Friend"] as! String 
        println(friendName) 
        self.friendsArray.append(friendName) 
       } 
      } 
     } 
     else { 
      // Log details of the failure 
      println("Error: \(error!) \(error!.userInfo!)") 
     } 
    } 


} 


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

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

    var cell:UITableViewCell = self.tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell 

    cell.textLabel?.text = self.friendsArray[indexPath.row] 

    return cell 
} 

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { 

} 

ответ

0

При вызове findObjectsInBackgroundWithBlock его делать именно то, что это название говорит, в частности его работает в фоновом режиме.

Между тем, пока его работа в фоновом режиме, ваш код представления таблицы продолжает работать на переднем плане, эффективно параллельно.

Так что ваша viewDidLoad функции выхода и numberOfRowsInSection будет называться следующим, но в то время, если findObjectsInBackgroundWithBlock еще не закончено, то friendsArray.count будет 0.

+0

Итак, что я могу сделать, чтобы исправить это? – Justin

+0

Подобно этому же вопросу вчера. Они используют асинхронный код только в другом месте. http://stackoverflow.com/questions/30361517/asynchronous-tableviewcell-data/30361658#30361658. Принципы и варианты решения схожи. – Gruntcakes

+0

Im confused, как я могу убедиться, что Im работает функция CellforRowAtIndexPath после ViewdidLoad, потому что я думаю, что ViewDidLoad или даже ViewDidAppear произойдут сначала. – Justin

1

Вам нужно позвонить [self.tableView reloadData]; в завершении блоке findObjectsInBackground: звонок.

0

Приложение не знает, когда ваши данные будут возвращены, так что вы должны явно обновить UITableView после того, как вы успешно получили данные. Используйте [self.tableView reloadData] для перезагрузки UITableView позже.

UITableView будет загружать только один раз, когда UIViewController загружается. Если у вас уже есть данные, то время, когда UIViewController загрузок. В противном случае количество строк будет 0 в первый раз, и метод делегата cellForRowAtIndexPath не будет вызываться.

findObjectsInBackgroundWithBlock - это асинхронный вызов, когда вы смотрите документацию. Это не похоже на его буквальное значение, что он работает в фоновом режиме. Это означает, что он не будет блокировать текущий поток, чтобы пользователи могли взаимодействовать с приложением.

+0

@ Kasik Async означает, что он не будет ждать ответа, чтобы вернуться к текущей теме. Это не значит, что он отправлен в другой поток. –

-1

Как mentionded другой намек вам нужно позвонить reloadData, но вам нужно вызвать его в основном потоке, чтобы увидеть результат как можно скорее

dispatch_async(dispatch_get_main_queue()) {self.tableView.reloadData()} 
+0

Он не отправил этот блок кода в другую очередь, он просто работает в основном потоке. Итак, 'self.tableView.reloaddata()' достаточно –

+0

@LucasHuang Я не знаю PFQuery, но findInBackground не звучит для меня как основной поток. Он может быть реализован так, что обратный вызов выполняется в основном потоке, но это необычно. И с другой стороны, с помощью dispatch_async почти бесплатно, и это не может сделать хуже. – Kasik

+0

Причина, по которой они реализованы всегда в основном потоке, потому что разработчики могут отправлять в другую очередь по своей воле. Если разработчики Parse помещают его в другие очереди, это не разработчики, чтобы контролировать его. Я тоже не думаю, что это их стиль. –

0

В конце вашего if error == nil{...} заявления, загружать данные таблицы как это:

if error == nil{ 
    //All that other stuff... 
    tableView.reloadData() 
} 

Кроме того, убедитесь ваш tableView имеет свой delegate и datasource подключен к контроллеру представления. Это может потребовать сдачи этого в viewDidLoad:

tableView.delegate = self 
tableView.datasource = self 

Я также нахожу странным, что ваш tableView объявлен weak, но это не может быть уместным.

Попробуйте эти вещи и сообщите нам, если у вас все еще есть проблемы. Удачи! :)

+0

Это 'слабый', потому что это IBOutlet, на который ссылается непосредственно из его xib-файла –

0

просто попробуйте эти вещи. он поможет вам после того, как вы получите массив элементов make reload uitableView. если вы используете раскадровка проверить розетку источника данных это вы не использовали раскадровку или XIB, то вы установите источник данных в кодировке Вайс

0

привет вы можете использовать как этот

public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

{ 


    let cell : UITableViewCell = tableView.dequeueReusableCell(withIdentifier: "cell")! as UITableViewCell 


    cell.textLabel?.text = app.str[indexPath.row] 




    print(" cell \(cell.textLabel?.text!)") 


    return cell 


} 

TableOutLet.reloadData()