Я знаю, что название не так объяснимо, но вот история: я разрабатываю браузерную игру, в основном используя JavaScript и библиотеку Mapbox.
Все работает хорошо на настольных компьютерах, Android и iOS, но в iOS появляется одна проблема: после запуска игры в течение нескольких минут телефон внезапно начинает иметь графические артефакты и отображает большую часть текста, скремблированного.
Вот несколько фотографий того, что начинается с телефона:
Мой вопрос: что именно в моем коде может вызвать это? Утечка памяти? ( LE: на самом деле это была утечка памяти)
Реальный вопрос: как получается, что вы можете почти полностью закрыть весь телефон, просто просматривая веб-страницу? Не следует ли Safari остановить это или, по крайней мере, iOS?
Это не проблема с этим конкретным устройством, так как эта проблема может быть воспроизведена на разных устройствах iPhone. (Я не так уверен в разных версиях iOS).
Как я могу воспроизвести ошибку:
- Откройте игру (внутри Safari).
- Пусть он работает 3-4 минуты.
- Сдвиньте центр уведомлений, и все сойдет с ума.
Я добавил видео YouTube, показывающее, как я могу воспроизвести ошибку (на моем iPhone 5C).
Кажется, что проблема сначала появляется в центре уведомлений (если вы прокручиваете меню сверху).
На данный момент эта проблема возникает только наiPhone 5C
iOS 9.2.1 (13D15). Это также происходит в новой версии iOS 9.3.
Чтобы исправить эту проблему, я должен:
- Закройте приложение Safari (в котором вкладка игры открыта).
- Блокировка телефона. После разблокировки все возвращается к норме.
Некоторые сведения о самой игре:
- В игре показана карта Mapbox и некоторые единицы по ней (маркеры).
- Сервер Node.js работает со скоростью 1 тик/секунду, и после каждого тика обновленное состояние игры отправляется в браузер через Socket.io.
- Каждый раз, когда браузер получает состояние игры, он соответствующим образом обновляет маркеры.
- * Игра может также обновлять маркеры, если вы увеличиваете или уменьшаете масштаб или выбираете их.
EDIT2:
Обнаружена утечка памяти (как и ожидалось). После исправления этой утечки (проверьте undefined
_icon) проблема больше не возникает. Это означает, что где-то вдоль этих строк запускается ошибка Safari/iOS.
Вот что именно вызывается каждый тик, для каждой группы, которая была сгруппирована (была скрыта и сгруппирована с другими внутри MarkerCluster):
var $icon = $(marker._icon); // marker._icon is undefined because of the clustering
$icon.html('');
$icon.append($('<img class="markerIcon" src="' + options.iconUrl + '" />'));
var iconX = 10;
var iconY = -10;
var iconOffset = 0;
for(var v in this.icons) {
this.icons[v].css('z-index', + $icon.css('z-index') + 1);
this.icons[v].css('transform', 'translate3d(' + iconX + 'px,'
+ (iconY + iconOffset) + 'px,' + '0px)');
iconOffset += 20;
this.icons[v].appendTo($icon);
}
// Fire rate icons
this.attackRateCircle = $('<div class="circle"></div>');
this.attackRateCircle.circleProgress({
value: 0,
size: 16,
fill: { color: "#b5deff" },
emptyFill: 'rgba(0, 0, 0, 0.5)',
startAngle: -Math.PI / 2,
thickness: 4,
animation: false,
});
this.attackRateCircle.hide();
// Create and display the healthbar
this.healthBar = $('<div>').addClass('healthBar ');
this.healthBar.css('z-index', $icon.css('z-index'));
this.healthBarFill = $('<span class="fill">');
this.healthBar.append(this.healthBarFill);
$icon.append(this.healthBar);
$icon.append(this.attackRateCircle);
И это массив icons
:
this.icons = {
attack_order: $('<img src="img/attack.png" class="status_icon">'),
attack: $('<img src="img/damage.png" class="status_icon icon_damage">'),
hit: $('<img src="img/hit.png" class="status_icon icon_hit">'),
};
circleProgress
вызов из этой библиотеки: https://github.com/kottenator/jquery-circle-progress
DEMO
Yay, я смог создать jsFiddle, который воспроизводит ошибку: https://jsfiddle.net/cte55cz7/14/ Откройте Safari на iPhone 5C и подождите пару минут. На iPhone 6 и iPad mini авария страницы (как и ожидалось из-за утечки памяти)
Здесь тот же код в HasteBin, для тех, кто не хочет его запускать.