2016-06-24 131 views
2

我使用Realm for Swift並將數據加載到UITableView中。當我進入屏幕時,大約有200個數據對象正在逐漸下載,所以在我的測試中有很多插入到我的測試中的UITableView被顯示後。我正在使用Realm示例將RealNolificationBlock與RealmCollectionChange儘可能地緊密結合,並且在此過程中偶爾會發生兩個單獨的崩潰。addNotificationBlock {RealmCollectionChange}在UITableView中崩潰

  1. ***由於未捕獲的異常'RLMException',終止應用程序,原因:'只能從runloops內添加通知塊。

即使我從我的ViewController類中的主線程中提取所有數據,也會發生這種崩潰。

  • ***斷言故障 - [UITableView的_endCellAnimationsWithContext:],/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit/UIKit-3512.30.14/UITableView .m:1720 ****由於未捕獲的異常'NSInternalInconsistencyException'而終止應用程序,原因:'無效更新:節0中的行數無效。更新(27)後現有節中包含的行數必須爲等於在更新之前包含在該部分中的行數(17),加上或減去從該部分插入或刪除的行數(插入9個,刪除0個)並且加上或減去移入或移出該部分(0移入,0移出)。'
  • 這個崩潰纔開始出現的我更換

    tableView.reloadData() 
    

    tableView.beginUpdates() 
         tableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
          withRowAnimation: .Automatic) 
         tableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
          withRowAnimation: .Automatic) 
         tableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, 
          withRowAnimation: .Automatic) 
         tableView.endUpdates() 
    

    在我addNotificationBlock的.Update()節後

    有我丟失的東西關於造成這種情況的領域?我懷疑這是由於我沒有完全理解這個圖書館的內在機制。

    這裏是我的代碼,以供參考:

    self.exhibits = DataManager.getAllExhibitsSorted("id") 
    token = self.exhibits?.addNotificationBlock { (changes: RealmCollectionChange) in 
        switch changes { 
        case .Initial(_): 
    
        self.exhibits = DataManager.getAllExhibitsSorted("id") 
        self.exhibitListTableView.reloadData() 
        break 
        case .Update(_, let deletions, let insertions, let modifications): 
    
        // Query results have changed, so apply them to the UITableView 
        self.exhibitListTableView.beginUpdates() 
        self.exhibitListTableView.insertRowsAtIndexPaths(insertions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
         withRowAnimation: .Automatic) 
        self.exhibitListTableView.deleteRowsAtIndexPaths(deletions.map { NSIndexPath(forRow: $0, inSection: 0) }, 
         withRowAnimation: .Automatic) 
        self.exhibitListTableView.reloadRowsAtIndexPaths(modifications.map { NSIndexPath(forRow: $0, inSection: 0) }, 
         withRowAnimation: .Automatic) 
        self.exhibitListTableView.endUpdates() 
    
        break 
        case .Error: 
        NSLog("Error in notificationBlock") 
        break 
        } 
    } 
    

    回答

    2

    這聽起來像你可能會在這裏過於複雜的東西一點點。

    領域Results對象是活的並且自動更新。在主運行循環的下一次迭代中,對其基礎對象所做的意義更改會自動更新,因此無需對它們執行手動重新獲取。在您的代碼中,在令牌生成後,您將在.Initial更改通知中重新分配self.exhibits,這可能會導致您的一些問題出現在此處。如果刪除該行,它應該繼續工作。

    我建議通過您的代碼,並確保self.exhibits只被分配一次,並且更改通知方法僅適用於該代碼。

    讓我知道如果這不能解決它。

    +0

    謝謝,這個伎倆! –

    +0

    呃。大部分時間都設法解決它,但是當我在下載過程中打開和關閉wifi時,仍然收到NSInternalInconsistencyException。這可能是notificationBlock之間的競爭條件。更新和self.exhibits中存在的值。即使只是一些關於如何捕捉錯誤的幫助也可能就足夠了。 .Update中的所有內容都應該拋出一個錯誤,所以我無法用do-catch來包圍它。 –

    +0

    爲什麼它值得我有完全相同的問題。你有沒有解決這個問題?這似乎是Realm內某處的競爭條件。我使用Realm文檔中顯示的代碼100%... –