2016-01-24 19 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

相關問題