2016-01-24 24 views
2

我有一个应用程序从Parse数据库中提取信息,并将其显示在UITableView中。我从viewWillAppear函数中解析信息,并将其显示在tableView(cellForRowAtIndexPath)函数中。有时候我收到一个错误,因为存储Parse信息的数组的长度为0,我尝试访问数组边界之外的索引处的信息。我相信这是因为在viewWillAppear完成运行之前,cellForRowAtIndexPath被调用。这是可能的还是我的错误肯定来自其他地方?在ViewWillAppear之前调用的CellForRowAtIndexPath完成运行

编辑:错误没有发生每次,我不能找到一种方法来复制它

override func viewWillAppear(animated: Bool) { 

    //begin ignoring events until the information is finished being pulled 
    UIApplication.sharedApplication().beginIgnoringInteractionEvents() 

    resultsArray.removeAll(keepCapacity: false) 

    //run query 
    let query = PFQuery(className: "Answers") 
    query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in 

     if let objects = objects { 

        //append information to the resultsArray 
       } 
      } 
      self.tableView.reloadData() 
     } 
    } 
    //information is now pulled, so allow interaction 
    UIApplication.sharedApplication().endIgnoringInteractionEvents() 

} 


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! answerCell 

    // THIS IS WHERE THE ERROR OCCURS 
    resultsArray[indexPath.row].imageFile.getDataInBackgroundWithBlock { (data, error) -> Void in 

     //set image within cell 
    } 
    return cell 
} 
+0

把一些代码从你身边 –

+0

请参阅代码@Graham – rohaldb

+0

请把一个破发点中的'cellForRowAtIndexPath'然后运行和走一步看一步是怎么回事。那么同一时间你可以看到你的arry是否为空。 –

回答

0

我建议你分析你的数据加载到一个临时数组,然后分配给你的属性数组,你叫reloadData权之前 - 这将避免任何潜在的竞争条件,并删除了removeAll的需求这是一个潜在的你的问题的很大一部分;

override func viewWillAppear(animated: Bool) { 

    //begin ignoring events until the information is finished being pulled 
    UIApplication.sharedApplication().beginIgnoringInteractionEvents() 



    //run query 
    let query = PFQuery(className: "Answers") 
    query.findObjectsInBackgroundWithBlock { (objects, error) -> Void in 

     var localArray=[SomeType]() 

     if let objects = objects { 

        //append information to the localArray 
       } 
      } 
      self.resultsArray=localArray 
      self.tableView.reloadData() 
     } 
    } 
    //information is now pulled, so allow interaction 
    UIApplication.sharedApplication().endIgnoringInteractionEvents() 

} 
+0

这很奇怪,这解决了这个问题。我想知道为什么会发生......但是,无论如何谢谢你! – rohaldb

+0

数组不是线程安全的,所以无论何时,当你从一个线程更新并从另一个线程读取时,你可能会遇到问题 – Paulw11

+0

@rohaldb,如果你看我的答案,你会发现“实际发生了什么”(进一步评论@ Paulw11 )。 – OhadM

0

看起来像viewWillAppear你有一个背景数据块findObjectsInBackgroundWithBlock有一些工作在不同的线程做(主线程的AKA),这意味着viewWillAppear将完成,而块会得到回调。

这解释了为什么cellForRowAtIndexPathviewWillAppear完成后因调用回调块而被调用。

这意味着一切都很好,并且viewWillAppear实际上完成了合法的“运行”。

实际上你可以放回调方法里面一个断裂点(在viewWillAppear)和突破点内cellForRowAtIndexPath,看回调时发生的同时cellForRowAtIndexPath被调用。

如果你需要与Parse不同的方法,也许你应该看看他们的documentation

0

其实如果你的回拨不能访问self.tableView,一切都会像往常一样继续。你可以试试。

它发生在我身上时,我访问视图在屏幕上initinit端调用的方法viewDidLoad方法。

无论如何,你应该知道这个事实。并且您在回调中访问您的tableView(在viewWillAppear完成之前调用),需要cellForRowAtIndexPath

+0

林不知道你的意思/如何解决它。 “实际上,如果你的回调不能访问self.tableView”是什么意思? – rohaldb

+0

你可以评论'self.tableView.reloadData()'然后看看会发生什么。 – SeanChense

+0

但后来的信息不会显示在表中? – rohaldb

相关问题