GMSPolyline非常大的记忆秒杀

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

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

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

使用Xcode仪器,我们在创build约25条聚合线时总共监测了23k个位置点(不是每个)的内存使用情况。 在创build多行的过程中,应用程序内存使用量从大约14 MB增加到大约172 MB,净峰值大约为158 MB。 不久之后,所有的多线创build,内存使用最终下降到约19 MB,似乎是稳定的,累计净额约5 MB,所以看来每个位置点需要大约220个字节(5 MB / 23K点)商店。

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

显然, GMSPolyLine结构不适用于我们要求的大量使用。

我们尝试用独立的自动释放池包装一些多行创build循环,然后在适当的位置排空这些循环,但这对内存使用没有影响。 创build多边形线后控制回到主运行循环的峰值内存使用根本没有变化。 后来变得清楚为什么; 在创build多行之后,Google Map系统才会释放资源,直到第一个DisplayLinkcallback。

我们接下来的工作就是手动调整我们在GMSPolyline中推送的数据量,可能会使用我们自己的边界testing,裁剪,修剪和最小化,而不是依靠Google地图来有效地完成这项工作。

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

所以问题是,处理这种情况的最好方法是什么?谷歌的某个人可以对GMSPolyline最佳实践,上限,瓶颈等方面GMSPolyline

为什么不尝试基于基本的http请求使用google API进行指导。 https://developers.google.com/maps/documentation/directions/ 。 (检查有关许可和请求的条件)。

然后用IOS MKPolyline绘制数据。 我肯定你会有更好的performance。 而你只会依靠谷歌的定位数据。

要将google API的响应转换为坐标,请使用以下熟知的方法(从其他post中获取):

 - (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; } 

我有一个类似的问题,在谷歌SDK的性能,它为我工作。