title: TableViewController wait loading data before objectAtIndex
body: <p>I have this code to load data from <strong>Parse</strong> in a TableView with Swift.
  The problem I have : </p>
  
  <ul>
  <li>When I touch a cell, that's open the detail view with the cell infos
   But when I return to the list view and touch another cell to fast, the data are not loaded and I have an error : </li>
  </ul>
  
  <blockquote>
    <p>NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2
    beyond bounds for empty array'</p>
  </blockquote>
  
  <p>How could I force waiting the view to load all the cell data before I can touch something ?
  I can put the loadData() call in the viewDidLoad method, but this way I'll be force to refresh manually the data each time I add a new cell, delete a cell...etc</p>
  
  <pre><code>class MasterTableViewController: UITableViewController {
  
     var alertsListData:NSMutableArray = NSMutableArray()
  
     func loadData(){
         alertsListData.removeAllObjects()
         var currentUser = PFUser.currentUser()
         if (currentUser != nil){
             var findAlertsData = PFQuery(className: "Alert")
             findAlertsData.whereKey("user_id", equalTo:PFUser.currentUser())
             findAlertsData.findObjectsInBackgroundWithBlock{
                 (objects:[AnyObject]!, error:NSError!)-&gt; Void in
                 if (error == nil){
                     for object in objects {
                         self.alertsListData.addObject(object)
                     }
                     self.tableView.reloadData()
                     self.refreshControl?.endRefreshing()
                 }
             }
         }
     }
  
     @IBAction func logoutAction(sender: AnyObject) {
         PFUser.logOut()
         var currentUser = PFUser.currentUser()
     }
  
     override func viewDidAppear(animated: Bool) {        
         self.loadData()
         ...
     }
  
     override func viewDidLoad() {
         super.viewDidLoad()
         var refresh = UIRefreshControl()
         refresh.attributedTitle = NSAttributedString(string: "Tirer pour rafraîchir")
         refresh.addTarget(self, action: "loadData", forControlEvents:.ValueChanged)
         self.refreshControl = refresh
  
         // Uncomment the following line to preserve selection between presentations
         //self.clearsSelectionOnViewWillAppear = false
  
         // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
         // self.navigationItem.rightBarButtonItem = self.editButtonItem()
     }
  
     override func didReceiveMemoryWarning() {
         super.didReceiveMemoryWarning()
         // Dispose of any resources that can be recreated.
     }
  
     // MARK: - Table view data source
  
     override func numberOfSectionsInTableView(tableView: UITableView?) -&gt; Int {
         // #warning Potentially incomplete method implementation.
         // Return the number of sections.
             return 1
     }
  
     override func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -&gt; Int {
         // #warning Incomplete method implementation.
         // Return the number of rows in the section.
         return alertsListData.count
     }
  
     override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {
         let cell:AlertTableViewCell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath:    indexPath) as AlertTableViewCell
         let alert:PFObject = self.alertsListData.objectAtIndex(indexPath.row) as PFObject
         cell.alertTitleLabel.text = alert.objectForKey("title") as? String
         var dateUpdated = alert.updatedAt as NSDate
         var dateFormat = NSDateFormatter()
         dateFormat.locale = NSLocale(localeIdentifier: "fr_FR")
         dateFormat.dateFormat = "EEEE d, à hh:mm"
         cell.alertDateLabel.text = NSString(format: "%@", dateFormat.stringFromDate(dateUpdated).capitalizedString)
         var status:Bool = alert.objectForKey("status") as Bool
         if (status == true){
             cell.alertStatus.text = "Terminée"
         }else{
             cell.alertStatus.text = "En cours"
         }
  
         return cell
     }
  
     /*
     // Override to support conditional editing of the table view.
     override func tableView(tableView: UITableView!, canEditRowAtIndexPath indexPath: NSIndexPath!) -&gt; Bool {
         // Return NO if you do not want the specified item to be editable.
         return true
     }
     */
  
     /*
     // Override to support editing the table view.
     override func tableView(tableView: UITableView!, commitEditingStyle editingStyle: UITableViewCellEditingStyle,    forRowAtIndexPath indexPath: NSIndexPath!) {
         if editingStyle == .Delete {
             // Delete the row from the data source
             tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
         } else if editingStyle == .Insert {
             // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
         }    
     }
     */
  
     /*
     // Override to support rearranging the table view.
     override func tableView(tableView: UITableView!, moveRowAtIndexPath fromIndexPath: NSIndexPath!, toIndexPath:    NSIndexPath!) {
  
     }
     */
  
     /*
     // Override to support conditional rearranging of the table view.
     override func tableView(tableView: UITableView!, canMoveRowAtIndexPath indexPath: NSIndexPath!) -&gt; Bool {
         // Return NO if you do not want the item to be re-orderable.
         return true
     }
     */
  
  
     // MARK: - Navigation
  
     // In a storyboard-based application, you will often want to do a little preparation before navigation
     override func prepareForSegue(segue: UIStoryboardSegue?, sender: AnyObject!) {
         // Get the new view controller using [segue destinationViewController].
         // Pass the selected object to the new view controller.
         if (segue!.identifier == "showDetails"){
             var selectedIndexPath:NSIndexPath = self.tableView.indexPathForSelectedRow()!
             var detailViewController:DetailViewController = segue!.destinationViewController as DetailViewController
             detailViewController.alertData = alertsListData.objectAtIndex(selectedIndexPath.row) as PFObject
         }
     }
  
     }
  </code></pre>
  
  <p>The Add controller is : </p>
  
  <pre><code>class AddViewController: UIViewController {
  
      @IBOutlet weak var titleTextField: UITextField!
      @IBOutlet weak var searchTextField: UITextField!
      @IBOutlet weak var urlTextField: UITextField!
  
      override func viewDidLoad() {
          super.viewDidLoad()
  
          // Do any additional setup after loading the view.
      }
  
      override func didReceiveMemoryWarning() {
          super.didReceiveMemoryWarning()
          // Dispose of any resources that can be recreated.
      }
  
      @IBAction func addButtonTapped(sender: AnyObject) {
          var toAdd = PFObject(className:"Alert")
          toAdd["title"] = titleTextField.text
          toAdd["user_id"] = PFUser.currentUser()
          toAdd["status"] = false
          toAdd.saveInBackground()
          self.navigationController?.popToRootViewControllerAnimated(true)
      }
  
      /*
      // MARK: - Navigation
  
      // In a storyboard-based application, you will often want to do a little preparation before navigation
      override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
          // Get the new view controller using segue.destinationViewController.
          // Pass the selected object to the new view controller.
      }
      */
  
  }
  </code></pre>