【发布时间】:2016-06-17 08:56:26
【问题描述】:
我知道标题没有那么解释性,但故事是这样的:我正在开发一个浏览器游戏,主要使用 JavaScript 和 Mapbox 库。
在桌面、Android 和 iOS 上一切正常,但在 iOS 上出现了一个问题:让游戏运行几分钟后,手机突然开始出现图形伪影,并显示大部分文字乱码。
我的问题是:我的代码中究竟是什么导致了这种情况?内存泄漏? (LE:原来是内存泄漏)
真正的问题是:你怎么能通过简单的浏览网页就几乎把整个手机都变砖了页? Safari 不应该阻止这一点,或者至少是 iOS 吗?
这不是这个特定设备的问题,因为这个问题可以在不同的 iPhone 设备上重现。 (我不太确定不同的 iOS 版本)。
我如何重现错误:
- 打开游戏(在 Safari 中)。
- 让它运行 3-4 分钟。
- 向下滑动通知中心,一切都变得疯狂。
我添加了一个YouTube video,展示了如何重现错误(在我的 iPhone 5C 上)。
问题似乎首先出现在通知中心(如果您从顶部向下滑动菜单)。
就目前而言,这个问题似乎只出现在iPhone 5CiOS 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
演示
是的,我已经能够创建一个重现错误的 jsFiddle:https://jsfiddle.net/cte55cz7/14/ 在 iPhone 5C 上的 Safari 上打开并等待几分钟。在 iPhone 6 和 iPad mini 上,页面崩溃(正如预期的那样,由于内存泄漏)
Here's the same code in a HasteBin, for anyone who doesn't want to run it.
【问题讨论】:
-
PS:在因在
SuperUser上发布问题而被否决后发布在 SO 上。我希望这被认为是提出这个问题的正确地方。 -
@wottle 我在我的 iPhone 5C 上测试过,另一个人在另一部 iPhone 上测试过(在另一个大陆:D),但我认为他的型号也是 5C(实际上是他告诉我的)关于那些文物)。明天我将在 iPhone 6 和 iPad mini 上进行测试。
-
无法在我的 iPhone 6 上重现。这可能是 CG 中的错误。你能把所有的 ios 版本信息和硬件信息一起发布吗?
-
哇!而且我认为 Windows 10 Mobile 上的屏幕撕裂很糟糕......
-
A) 我什至没有生气。棒极了。 B)我有点想知道这是否真的可以用作漏洞利用,因为您显然正在访问您不应该能够访问的内存,并且 C)我认为有趣的是,一切总是向左倾斜。这向我表明,出于某种原因,您要么增加某些纹理的音高(也称为步幅),要么修改 GPU 的音高逻辑。绝对是 Safari/iOS/固件错误。
标签: javascript ios iphone safari artifacts