2015-05-21 105 views
0

我想查询使用解析将字符串添加到数组。然后我想把这些字符串放到我的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在ViewdidLoad之后运行CellforRowAtIndexPath函数,因为我认为ViewDidLoad或者甚至是ViewDidAppear都会先发生 – Justin

1

你需要调用[self.tableView reloadData];中的完成块拨打电话findObjectsInBackground:

0

该应用程序不知道您的数据将何时返回,因此您必须在成功接收数据后明确刷新UITableView。使用[self.tableView reloadData]稍后重新加载UITableView

UITableView将只加载一次,当UIViewController被加载。除非,你已经有数据加载时的时间UIViewController。否则,第一次的行数将为0,并且不会调用委托方法cellForRowAtIndexPath

findObjectsInBackgroundWithBlock是您查看文档时的异步调用。它不像它的字面含义,它在后台运行。这意味着它不会阻塞当前线程,以便用户仍然可以与应用程序进行交互。

+0

@Kasik异步意味着它不会等待响应返回到当前线程。这并不意味着它被分派到另一个线程。 –

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

另外,请确保您的tableViewdelegatedatasource连接到您的视图控制器。这可能需要把这个在viewDidLoad

tableView.delegate = self 
tableView.datasource = self 

我也觉得奇怪,你tableView被声明为weak,但可能是不相关的。

尝试这些事情,让我们知道如果你仍然有麻烦。祝你好运! :)

+0

这是'弱',因为它是一个IBOutlet,它直接从他的xib文件中引用 –

0

只是试试这些东西。它会帮助你 之后,你得到元素的数组重新加载uitableView。 如果你用故事板检查数据源出口 它,你没有用故事板或XIB,那么你在编码设置数据源wisse

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