GMSPolyline非常大的记忆秒杀?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (59)

在GPS应用程序中,用户可以显示我们称之为各种不同类型地图上轨道的复杂位置点列表,每个轨道可以包含2k到10k个位置点。在非Google地图类型中渲染时,轨道会被大量修剪,修剪和路径简化。这是为了保持内存使用率和性能。我们通常只会在OpenGL流水线上提交远远少于一千(聚合)的转换位置点,即使在最糟糕的情况下。

在整合Google Maps SDK for iOS时,我们最初试图继续利用我们自己的OpenGL轨道渲染系统,但遇到OpenGL上下文冲突的问题(渲染工作正常,但我们无法将GMSMapView和我们自己的OpenGL内部资源以释放没有人触摸删除的内存)。

因此,我们正在尝试利用GMSPolyline结构,并让Google SDK进行轨道呈现,但是我们遇到了主要的内存使用问题,并且正在寻找解决这些问题的指导。

使用Xcode Instruments时,我们在创建约25条多线时监视了内存使用情况,总共约有23k个位置点(不是每个点)。在创建多行的过程中,应用程序内存使用量从约14 MB增加到约172 MB,净峰约为158 MB。在创建所有多行之后不久,内存使用率最终回落到19 MB左右,并且看起来很稳定,累计净值约为5 MB,因此看起来每个位置点需要大约220个字节(5 MB / 23k点)商店。

什么伤害我们是高峰内存使用情况。尽管我们的实验室测试只使用了23k个位置点,但在现实世界中通常还有更多,而iOS似乎在Google地图iPhone 5上消耗大约450 MB 之后放弃了我们的应用程序(而我们的内部多线渲染系统达到了峰值相同测试用例为12 MB)。

很明显,该GMSPolyLine构造不适用于我们要求的重量级使用。

我们尝试用独立的自动释放池包装一些多线创建循环,然后在适当的点处耗尽这些循环,但这对内存使用没有影响。创建多行后控制返回主运行循环的峰值内存使用完全没有改变。后来它明白了为什么; Google Map系统不会释放资源,直到创建poly行之后的第一个DisplayLink回调。

我们的下一步工作是手动调整我们在GMSPolyline中推送的数据量,可能会使用我们自己的边界测试,裁剪,修剪和最小化,而不是依靠Google地图高效完成此操作。

这里的缺点是,这意味着更多的GMSPolyline对象将被分配和释放,可能在用户在地图上进行平移/缩放的时候。这些对象中的每一个都将具有更少的位置点,但是我们仍然担心这种方法的不可预见的后果,即许多GMSPolyline分配和释放的隐藏开销。

所以问题是,处理这种情况的最佳方法是什么?谷歌的某个人可以从任何GMSPolyline最佳实践,上限,瓶颈等方面了解一些情况吗?

提问于
用户回答回答于

根据基本的http请求尝试使用google API进行指导。

然后用IOS MKPolyline绘制数据。我确信你会有更好的表现。而且你只会依赖谷歌的定位数据。

要将google API的响应转换为坐标,请使用下面众所周知的方法:

- (NSMutableArray *)parseResponse:(NSDictionary *)response
{
    NSArray *routes = [response objectForKey:@"routes"];
    NSDictionary *route = [routes lastObject];
    if (route) {
        NSString *overviewPolyline = [[route objectForKey: @"overview_polyline"] objectForKey:@"points"];
        return  [self decodePolyLine:overviewPolyline];
    }
    return nil;
}


-(NSMutableArray *)decodePolyLine:(NSString *)encodedStr {

    NSMutableString *encoded = [[NSMutableString alloc]initWithCapacity:[encodedStr length]];
    [encoded appendString:encodedStr];
    [encoded replaceOccurrencesOfString:@"\\\\" withString:@"\\"
                                options:NSLiteralSearch range:NSMakeRange(0,
                                                                          [encoded length])];
    NSInteger len = [encoded length];
    NSInteger index = 0;
    NSMutableArray *array = [[NSMutableArray alloc] init]; NSInteger lat=0;
    NSInteger lng=0;
    while (index < len) {
        NSInteger b; NSInteger shift = 0; NSInteger result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlat = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lat += dlat;
        shift = 0; result = 0; do {
            b = [encoded characterAtIndex:index++] - 63; result |= (b & 0x1f) << shift;
            shift += 5;
        } while (b >= 0x20);
        NSInteger dlng = ((result & 1) ? ~(result >> 1)
                          : (result >> 1)); lng += dlng;
        NSNumber *latitude = [[NSNumber alloc] initWithFloat:lat * 1e-5]; NSNumber *longitude = [[NSNumber alloc] initWithFloat:lng * 1e-5];
        CLLocation *location = [[CLLocation alloc] initWithLatitude: [latitude floatValue] longitude:[longitude floatValue]];
        [array addObject:location]; }
    return array;
}

我在google sdk上遇到了类似的问题,并且对我很有用。

扫码关注云+社区

领取腾讯云代金券