2015-12-15 57 views
0

我有以下代碼:爲什麼我在同一時間插入和刪除UITableView會崩潰?

@property (nonatomic, strong) NSMutableArray *rows; // pre-filled with 2 rows 

// ... 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return self.rows.count; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSIndexPath *newRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section]; 
    MyRowRepresentation *newRowRepresentation = [MyRowRepresentation new]; 
    [self.rows insertObject:newRowRepresentation atIndex:newIndexPath.row]; 

    NSMutableIndexSet *indicesToRemove = [NSMutableIndexSet indexSet]; 
    NSMutableArray<NSIndexPath*> *indexPathsToRemove = [NSMutableArray array]; 

    for (int i = 0; i < self.row.count; i++) 
    { 
     MyRowRepresentation *mrr = self.rows[i]; 
     if (mrr != newRowRepresentation && [self meetsDeletionRequirements:mrr]) 
     { 
      [indicesToRemove addIndex:i]; 
      [indexPathsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:indexPath.section]]; 
     } 
    } 

    [tableView beginUpdates]; 
    [tableView insertRowsAtIndexPaths:@[newRowIndexPath] withRowAnimation:UITableViewRowAnimationTop]; 
    [self.rows removeObjectsAtIndexes:indicesToRemove]; 
    [tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationTop]; 
    [tableView endUpdates]; // crash here 
} 

當我選擇一排,我得到這個:

2015-12-14 20:27:17.761 Now[1685:1753114] ERROR CRASH #(null) attempt to insert row 3 into section 1, but there are only 3 rows in section 1 after the update 
2015-12-14 20:27:17.828 Now[1685:1753114] ERROR Stack Trace: (
    0 CoreFoundation      0x0000000185684248 <redacted> + 160 
    1 libobjc.A.dylib      0x00000001970a80e4 objc_exception_throw + 60 
    2 CoreFoundation      0x00000001856840ec <redacted> + 0 
    3 Foundation       0x0000000186538ed4 <redacted> + 112 
    4 UIKit        0x000000018a2e57ec <redacted> + 5256 
    5 Now         0x0000000100092914 -[MyTableViewController tableView:didSelectRowAtIndexPath:] + 1234 
    ... 
) 
2015-12-14 20:44:48.933 Now[1692:1754780] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 3 into section 1, but there are only 3 rows in section 1 after the update' 

但我很困惑;以下步驟應該工作,不是?

  1. 我將新行表示法插入到我的跟蹤數組中。
  2. 我在桌面上開始更新,應該將其置於「暫停」狀態。
  3. 我刪除了我不希望從我的跟蹤陣列,其中不包括新的行表示。
  4. 我刪除了與刪除的行表示相對應的表視圖行。
  5. 我插入對應於新行表示的表視圖行。

要崩潰應用程序,我選擇其中一個原始2行,然後選擇其中一個。

我不明白是什麼導致它崩潰?

+0

移動的'beginUpdates'到頂部,方法 – Paulw11

+2

對'deleteRowsAtIndexPaths'的調用必須在調用'insertRowsAtIndexPaths'之前。 – rmaddy

+2

@ Paulw11沒有必要移動'beginUpdates'。它只需要在調用各種表修改方法之前。 – rmaddy

回答

0

我不能回答爲什麼,但我沒有用一個單一的重載調用而不是多個插入/刪除通話解決這個問題:

@property (nonatomic, strong) NSMutableArray *rows; // pre-filled with 2 rows 

// ... 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return self.rows.count; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView beginUpdates]; 
    NSIndexPath *newRowIndexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section]; 
    MyRowRepresentation *newRowRepresentation = [MyRowRepresentation new]; 
    [self.rows insertObject:newRowRepresentation atIndex:newIndexPath.row]; 

    NSMutableIndexSet *indicesToRemove = [NSMutableIndexSet indexSet]; 
    NSMutableArray<NSIndexPath*> *indexPathsToRemove = [NSMutableArray array]; 

    for (int i = 0; i < self.row.count; i++) 
    { 
     MyRowRepresentation *mrr = self.rows[i]; 
     if (mrr != newRowRepresentation && [self meetsDeletionRequirements:mrr]) 
     { 
      [indicesToRemove addIndex:i]; 
      [indexPathsToRemove addObject:[NSIndexPath indexPathForRow:i inSection:indexPath.section]]; 
     } 
    } 

    [tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic]; 
    [tableView endUpdates]; 
}