Swift: сбой при многократной загрузке таблицы

У меня следующая проблема:

В моем приложении у вас есть онлайн-рецепты, теперь представьте себе TabViewController. На первых двух страницах этого TabViewController у вас есть представление, отображающее рецепты, хранящиеся в базе данных в реальном времени Firebase. На третьем у вас есть простой вид с некоторыми кнопками, но Firebase не используется и не импортируется. Проблема теперь в том, что когда я несколько раз хлопаю по нижней панели и, следовательно, переключаю TabViewController несколько раз за секунду, приложение вылетает. Вероятно, это из-за того, что Firebase перезагружается каждый раз, так как происходит изменение TabViewController, что может привести к перегрузке.

Теперь я получаю следующую ошибку:

Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444
2020-05-22 16:44:28.057640+0200 GestureCook[10451:3103426] Fatal error: Index out of range: file /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1103.2.25.8/swift/stdlib/public/core/ContiguousArrayBuffer.swift, line 444

Он выделяет этот код let recipe = myRecipes[indexPath.row]с индексом вне допустимого диапазона. Как теперь уменьшить нагрузку на сервер или избежать этой ошибки?

Причина увеличения нагрузки, вероятно, связана с тем, что мне нужно получить несколько рецептов из разных мест одновременно, как в этом упрощенном примере:

// dict is a list of recipe IDs
// And the GetRecipeService.getRecipe is a service which gets a recipe using a .observeSingleEvent (this causes these requests)

for child in dict {
                GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
                    self.myRecipes.append(recipe ?? [String:Any]())
                    }
                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
                }
            }

Как уменьшить нагрузку? Есть ли что-то вроде многопутевого обновления в Firebase, но просто как получить, чтобы мне не нужно было загружать 10-20 рецептов с помощью.observeSingleEvent?

1 ответ

Решение

Прежде всего DispatchQueueблок находится не в том месте. Он должен быть внутри крышки

GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
   self.myRecipes.append(recipe ?? [String:Any]())
   DispatchQueue.main.async {
      self.tableView.reloadData()
   }
}

Для управления несколькими асинхронными запросами в цикле существует API: DispatchGroup

let group = DispatchGroup()
for child in dict {
    group.enter()
    GetRecipeService.getRecipe(recipeUID: child.key) { recipe in
        self.myRecipes.append(recipe ?? [String:Any]())
        group.leave()
    }
}

group.notify(queue: .main) {
    self.tableView.reloadData()
}
Другие вопросы по тегам