yandex / mapkit-ios-demo

MapKit iOS demo
Other
84 stars 27 forks source link

Переиспользование инстансов карт для экономии памяти #235

Closed pavelhiq closed 5 months ago

pavelhiq commented 6 months ago

Если есть необходимость отображать карту сразу на нескольких экранах в навигационном стеке, то использование отдельных инстансов значительно увеличивает потребление памяти приложением -- повышается риск принудительного завершения системой. Только что созданный инстанс YMKMapView(frame: .zero), еще до появления на экране и отображения области карты и её объектов, прибавляет около 2.5Мб, что само по себе немало.

Как высвободить максимальный объем памяти, связанной с инстансом карты, чтобы дальше переиспользовать его на другом экране?

Возможно, с учетом понимания деталей реализации у вас есть готовые рекомендации на эту тему.

Еще заметил, что в последних версиях пропал YMKMapWindow.onMemoryWarning(). Судя по всему, обработка таких предупреждений полностью скрыта внутри. Что именно сейчас происходит при этом? Может ли что-то дополнительно сделать клиент библиотеки?

pavelhiq commented 5 months ago

что скажете, @YandexMapKit?

YandexMapKit commented 5 months ago

Чтобы дать подходящие рекомендации, расскажите подробнее о сценарии использования библиотеки, который вы реализуете. Особенно интересно: что подразумевается под «отображением карты сразу на нескольких экранах в навигационном стеке»?

pavelhiq commented 5 months ago

@YandexMapKit, можно взять типичный сценарий с поиском чего-либо на карте. Допустим, этот сценарий предполагает использование UINavigationController. Собственно, для отображения найденных объектов на карте используется 1й инстанс. Дальше можно перейти на экран детального описания объекта, где, к примеру, будет отображаться небольшая карта-превью - 2й инстанс. При нажатии на него можно переходить к полноэкранной карте с набором POI-маркеров в окрестности нашего объекта - 3й инстанс. Итого в памяти будет одновременно три инстанса YMKMap, хотя на каждом из шагов видимым будет только один.

YandexMapKit commented 5 months ago

Если вы не хотите использовать несколько инстансов, можно переиспользовать один, если положить его во Fragment. Если такой вариант вам не нравится, можете у невидимых звать wipe для невидимых instance. Этот вариант потребует больше памяти, чем вариант с одним инстансом, но код будет проще. Можете начать с простого варианта (wipe) и посмотреть, устраивает ли такой расход памяти. Wipe очищает только кеши в RAM, поэтому повторных загрузок данных из-за него не будет.

Что касается Decoding style: JSON size: 1584603 bytes, тут речь про исходный json, который мы декодируем. К размеру стиля в оперативной памяти это отношения не имеет. resetMapStyles() действительно сбрасывает кастомизацию стилей, но не имеет отношения к потреблению памяти. Стили — это не то, на что стоит смотреть для уменьшения потребления памяти, поскольку расход памяти инстансом карты — сотни мегабайт.