#ios #swift #memory #dispatch-queue
Вопрос:
У меня есть приложение, которое постоянно считывает данные с моего сервера и обновляет данные в пользовательском интерфейсе. Он извлекает довольно много данных, создает некоторые структуры данных, а затем передает информацию в пользовательский интерфейс. Приведенный ниже код показывает, как я собираю данные:
class Server {
private var units: [Unit] = []
...
init {
// I pull data from a firebase realtime database here using the observe method
// which triggers the callback everytime the data changes
// 'data' is a big dictionary of dictionarys which will be sorted into objects
FirebaseDatabaseHandler.getServerInfo(serverAddress: address, callback: { data in
// Because its a lot of data sorting it is hefty so I do this on a background thread
// 'updateQueue' is a single static DispatchQueue that I create in AppDelegate for now
AppDelegate.updateQueue.async {
// here I create an array of data objects using the JSON I pulled from firebase
// then I set the "units" variable of this object and call my update callback
// which triggers a UI update on the main thread
if let unitData = (data?["units"] as? [String:Any]) {
var unitsArray = [Unit]()
for key in unitData.keys {
unitsArray.append(Unit(address: key.base64Decode, data: unitData[key] as! [String:Any]))
}
self.units = unitsArray
self.updateCallback()
}
}
})
}
...
Приведенный выше код работает нормально, однако память постоянно увеличивается и не освобождается должным образом, после запуска в течение ~ 10-20 минут приложение создает до 2 ГБ памяти и выходит из строя из-за нехватки памяти.
Если я избавлюсь от AppDelegate.updateQueue.async { }
и просто позволю этому коду выполняться в основном потоке, память ДЕЙСТВИТЕЛЬНО очищается, и сбоев нет, память остается около 50-200 МБ, однако, если я это сделаю, пользовательский интерфейс, по сути, навсегда зависает из-за того, сколько обработки происходит в основном потоке
Я пытался использовать отладчик для просмотра размера моего units
массива и моего Server
объекта, но ни один из них не увеличивается в размерах независимо от того, как долго работает приложение.
Могу ли я что-нибудь сделать для отладки этого или по какой-либо причине, по которой память не будет очищаться при запуске из фонового потока?
Комментарии:
1. Вы пробовали использовать инструменты для отладки поведения памяти вашего приложения? ( developer.apple.com/videos/play/wwdc2019/411 )
2. Я пытаюсь создать вашу проблему с помощью примера проекта, работающего в глобальном фоновом потоке, по-прежнему удаляю выделение, не могу воспроизвести вашу проблему
3. @AchmadJP Я посмотрю, смогу ли я придумать простой способ воспроизведения… возможно, я все равно найду проблему при этом: P спасибо за усилия
Ответ №1:
Добавить [слабый self]:
FirebaseDatabaseHandler.getServerInfo(serverAddress: address, callback: {[weak self] data in
AppDelegate.updateQueue.async { [weak self] in
Обратите внимание, что вам нужно будет внести еще некоторые коррективы, потому что self станет необязательным.
Комментарии:
1. Просто попробовал это, похоже, все еще возникает та же проблема — попытается создать простой способ ее воспроизведения