簡體   English   中英

具有多個NSFetchedResultsControllers的UITableView導致斷言失敗

[英]UITableView with multiple NSFetchedResultsControllers causing Assertion failure

我有一個包含3個部分的UITableView,每個部分都通過唯一的NSFetchedResultsController進行饋送。

插入,更新...表時,我從NSFetchedResultsController -controllerDidChangeContent獲取斷言失敗

我的猜測是以下方法中出現indexPaths的問題,因為每個控制器只有一個(0)部分,而對於第0部分中的控制器,不會發生故障。

- (void)controller:(NSFetchedResultsController*)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath*)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath*)newIndexPath
{
    switch(type)
    {
        case NSFetchedResultsChangeInsert:
            [[self atableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case NSFetchedResultsChangeDelete:
            [[self atableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
            break;
        case NSFetchedResultsChangeUpdate:
            [self configureCell:(DashboardViewCell *) [[self atableView] cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
            break;
        case NSFetchedResultsChangeMove:
            [[self atableView] deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [[self atableView] insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    } 
}

所以我的問題是,如何確定正在處理哪個控制器(從哪個部分開始)並相應地修改indexPath?這是否是正確的方法? 以及在一個uitable視圖中使用多個nsfetchedresultsscontrollers的任何示例。

所以我的猜測實際上是正確的:

當每個控制器進入以下功能時

  • (void)控制器:(NSFetchedResultsController *)控制器didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

除了為第0節設置的控制器以外,每個控制器的indexPath都是錯誤的。

每個控制器只有一個部分-在我的情況下為0,但更重要的是,這些部分與表部分不對應。

因此,我當前實現的解決方法(不太好,所以可能會重做)是檢查控制器的cacheName並基於此修改indexPath / newIndexPath的部分

像這樣的東西:

if([[controller cacheName] isEqualToString:@"sectionX"])
{
  indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:<add correct section>];
  newIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:<add correct section>];
}

我不確定這是FetchedResultController。

插入和刪除行調用有時會要求tableView重新加載,然后它將向委托和數據源方法詢問numberOfRowsInSection,cellForRowAtIndexPath等。

可能發生的情況是模型和tableView不同步,並導致控制器發出警告。

    [tableView beginUpdates];

     if (editingStyle == UITableViewCellEditingStyleDelete) {

        NSMutableDictionary *item = [self.itemList objectAtIndex:indexPath.row];
    // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
        [self.itemList removeObjectAtIndex:indexPath.row];      

}   
    [tableView endUpdates];

嘗試類似的方法,其中對tableView和基礎模型的所有更改都包裝在beginUpdates和endUpdates中。 這些將導致tableView等待單元格的繪制,直到您單擊“確定”為止。

如果不是上述情況,這就是我通常在tableView中處理多個部分的方式。

在標頭中,為各節聲明一個typedef枚舉;

typedef enum {

    SectionTypeName,
    SectionTypeAge,
    SectionTypeSkills,

} SectionType;

//in the implementation

switch (indexPath.section) {
    case SectionTypeName:
        //do thing in the name section
        break;
    case SectionTypeAge:
        //do thing in the name section
        break;
    case SectionTypeSkills:
        //do thing in the name section
        break;          
    default:
        break;
}

我幾乎在每個tableView委托/數據源方法中都有switch()。 這樣可以很容易地弄清楚正在處理的部分及其功能。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM