谷歌地图在IOS7上崩溃。

42

我们正在开发一个混合应用程序,并在应用程序中使用Google地图API。当我们试图在地图上加载2000个数据标记时,它崩溃了。在IOS6和IOS5中,地图没有崩溃。这只发生在IOS7中。是否对IOS7应用程序进行了任何与内存相关的更改。


这里也遇到了相同的问题。崩溃也发生在Chrome(iOS7)中。我正在使用'markerwithlabel.js',并想知道那是否可能是问题的一部分。https://code.google.com/p/google-maps-utility-library-v3/wiki/Libraries - adamwjohnson5
在Craigslist移动站点上启用Google Maps进行房屋搜索会导致Safari在iOS7中崩溃。 - Stephen
1
是的,我使用Infobox插件在标记上显示标签,这就是为什么它在iOS7上崩溃的原因。 Infobox插件肯定会使用相同的API来完成此操作。 - Philipp Kühn
1
我认为这与我遇到的问题有关。我的 Web 应用程序崩溃,因为图像使用的内存没有被正确释放。请参见 https://dev59.com/8nfZa4cB1Zd3GeqPS4pQ - Mark
我们有同样的问题 - iOS 6和7之间的差异令人惊讶。我们已经尝试了下面许多建议,但仍然觉得应用程序总是在极限处运行。非常感谢任何建议。 - Daniel Williams
11个回答

13

正如之前所说,iOS7 在内存使用方面更加严格。这种行为也会出现在其他浏览器中,例如 Chrome,当应用程序达到内存使用上限时,就会发生崩溃。

我已经使用 Gmaps javascript API 和 jQuery 隔离了两个测试案例:

测试 100 个标记:一切正常

http://jsfiddle.net/edfFq/6/embedded/result

测试 3000 个标记:发生崩溃

http://jsfiddle.net/edfFq/7/embedded/result/

$(document).ready(function () {
    var map;
    var centerPosition = new google.maps.LatLng(40.747688, -74.004142);


    var options = {
        zoom: 2,
        center: centerPosition,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    map = new google.maps.Map($('#map')[0], options);


    for (var i=0;i<2800;i++){        
      var position = new google.maps.LatLng(40*Math.random(),-74*Math.random());
      var marker = new google.maps.Marker({
            position: position,
            map: map           
        });
    }
});

如果您的地图使用标签、自定义图标和聚合,您可以使用更少的标记来获取崩溃。


8

我曾遇到过类似的谷歌地图问题,于是我尝试分离出一个最小化测试案例。我想看看这是否是一个更普遍的内存管理问题。

下面这段代码只是在数组中存储了随机数据,但却会导致在16GB iPad mini上的IOS 7上Safari浏览器崩溃:

function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i) result += chars[Math.round(Math.random() * (chars.length - 1))];
    return result;
}

var arr = []
for (var i=0;i<5000;i++) {
    // one character is two bytes in JavaScript, so 512 chars is 1Kb:
    o = randomString(512, '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
    arr.push(o);
}

您可以通过访问http://vici.org/memtest.html,在自己的浏览器上尝试此测试。该页面上的脚本会尝试以1MB的步长占用50MB的内存。该脚本显示一个运行计数器,因此您将看到您的浏览器的运行情况以及它何时崩溃(如果出现)。该脚本将每个ip /用户代理组合的结果存储在数据库中,以便能够得出一些结论。
平均而言,IOS 6(n = 12)允许脚本占用约12MB。 IOS 7(n = 47)允许脚本占用约15 MB。这些不是硬限制。对于两个集合,标准偏差相当高,约为12 MB。在Xcode模拟器中,Safari甚至根本不会崩溃(宣称完整的50MB,可能是因为它可以访问更多RAM)。
因此,我们可以得出结论,问题并不是由IOS 7为Safari留下了更少的内存引起的。问题似乎是,正如Philipp Kühn所建议的那样,在某些特定情况下Safari消耗的内存比IOS 6中多得多。关于原因的一个线索可以在https://discussions.apple.com/message/23837361#23837361中找到,其中包含200个div和以下CSS的页面。
div {
  -webkit-backface-visibility: hidden;
}

崩溃了safari。

使用Leaflet库似乎可以避免地图问题(请参见https://code.google.com/p/gmaps-api-issues/issues/detail?id=https://github.com/Leaflet/Leaflet/pull/2149),但是Leaflet并没有通过css的改变来避免低内存崩溃,而是在javascript级别上进行了规避处理。现在,Leaflet避开了像这样的声明

context = this

这表明Safari没有清理未使用的对象。只要苹果不修复Safari,或许谷歌可以实施与Leaflet开发者类似的修改?同时,苹果已经发布了IOS7.1,虽然它并不能完全解决崩溃问题,但肯定会使它们更少地出现。

8
我们有一个网络应用程序,在iOS7上使用大量标记也会崩溃。因此,我们仔细研究了iPad使用的内存情况。
iPad mini(和iPad3)在iOS7上:
内存使用量越来越高,在300-400MB之间浏览器就会崩溃。
iPad 3在iOS6上:
内存使用量约为200MB,一切正常。
iPad 1在iOS5上:
内存使用量仅约为100MB,一切正常。
结论:
因此,这不仅仅是内存限制 - 这绝对是iOS safari上的一个巨大bug!截至目前(iOS 7.0.3),这个问题还没有得到解决。

移动网站在iPad的IOS 7.0.3上崩溃,但在iPhone上却没有,这是有原因的吗?我通过防止加载额外标记来使iPhone上的移动网站正常工作,但同样的策略对iPad无效。这是设备相关的问题(例如,打开太多应用程序),还是iPad比iPhone有更多限制? - KDP
今天发布了iOS 7.0.4版本。您能否检查问题是否仍然存在? - Mark
1
问题仍然存在:/ - Philipp Kühn

4

好消息!我们把应用程序框架从Google切换到了Leaflet,它的性能非常好,不会崩溃。我们检查了调试信息,发现它的内存使用非常高,但从未出现过崩溃情况。如果您还没有选择Leaflet,请尝试一下,它完全支持iOS 7。


3
我们的应用在 iOS 7 之前都能正常运行,但是之后却崩溃了,和其他用户遇到的问题相同。问题很可能是内存问题,你可以通过检查设备上的崩溃报告日志来验证。
由于我们的应用对客户至关重要,所以我们不能坐等苹果修复。在我们的情况下,修复涉及三个具体策略:
1. JavaScript 代码优化。我们的应用程序开发非常迅速,从原型变成可工作的系统,没有进行广泛的代码规划。在我们的系统中,通过优化代码,我们能够实现显著的内存节省。这意味着删除未使用的变量;如果您恰好将所有标记存储到预处理数组中作为数据库响应,请查看并在成功加载后删除这些旧数组和未使用的变量。此外,考虑限制包含的库,并采用常见的 JavaScript / jQuery 最佳优化实践。
2. 空白信息窗口。下一个节省内存的策略来自于不预加载每个标记的信息窗口屏幕数据。我们剥离了每个信息窗口的内容,只留下一个带有唯一 ID 的空 div,然后通过 Ajax 异步加载。当你把所有不必要的信息窗口数据都拿出来时,成千上万个标记的节省是相当大的。我们正在加载约 10,000 个标记。用户体验也没有受到很大影响,因为预加载和 Ajax 加载时差不多。
3. 最大的差别,也许是 iOS 7 内存泄漏位置的线索,来自于简单地减少同时显示在屏幕上的标记数量。每个应用程序都会有所不同,但我们发现将结果降至 500 个标记以下会导致一个稳定的系统而不会崩溃。我们的策略只是基于用户行为加载和清除可见标记数组。例如,如果用户的特定过滤器选择导致超过 500 个标记,我们就简单地限制了数据库中的结果。从视觉上看,结果集仍然很大,并且从用户体验的角度来看,与看到成千上万的标记没有太大区别。在两种情况下,用户仍然需要过滤和缩小结果以获得可管理的结果。在我们的情况下,用户甚至不会注意到限制。
这招有效了!我们的应用现在没有崩溃了。考虑到这个问题给我带来的时间(更不用说沮丧!),希望这些策略能为您提供一个起点,让您的应用程序恢复正常工作。如果您需要更具体的内容,请随时与我们联系。祝你好运!

0
我们在谷歌地图标签上遇到了相同的问题。当地图缩放时,应用程序会崩溃。这是在升级到IOS 7之后开始发生的。我正在尝试不同的选项,如在“拖动”和“空闲”事件中删除和添加标签。这段代码可以工作,但仍然会发生崩溃,但发生的频率较少。我希望有人能够提供更好的解决方案。
    google.maps.event.addListener(Map.gmap, 'drag', function () {
            $('.arrowSite_box').remove(); // remove labels
    });

    google.maps.event.addListener(Map.gmap, 'idle', function () {
        loadMarkers(results); // add labels
    });

0

我曾经遇到过同样的问题并尝试了一些方法。当标记被设置时(我一次添加了大约30个),我禁用了动画,现在看起来它不会再崩溃了。希望这可以帮到你。


嗯,我一次性添加了500到2000个标记,并且还进行了很多计算。Safari在这种情况下不会崩溃(尽管速度有点慢),但是当我快速缩放时它就会崩溃。 - ProblemsOfSumit

0

嘿...我也遇到了类似的问题。所以,我尝试了这个:

在我的视图控制器和自定义插件的“didReceiveMemoryWarning”方法中清除应用程序缓存,并在CDVPlugin类的“onMemoryWarning”方法中将属性和变量设置为NIL。这种方法对我有用。目前我没有遇到任何崩溃。 希望这可以帮助你。


0

看起来在iOS 7.1中已经修复了

昨天在iOS 7.0.6上,当地图有超过3,000个标记时会导致移动Safari崩溃。今天升级我的iPad后,在移动Safari中可以加载拥有15,000多个标记的地图。


0
如果你正在处理大量的标记,请尝试使用MarkerClusterer。它将显著降低并发标记的数量,在我们的情况下,它防止了崩溃的发生。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接