Я так понял, что при каждом вызове tableView.insert, tableView.remove идет пересчет numberOfRows - пересчитывается внутри View, а не с помощью делегата. Из-за того, что удаляется в разнобой, то может оказаться, что верхняя часть таблицы удалилась, а прилете IndexPath нижней, значение которого >= кол-ву строк.