2

在 iOS 中使用 Skobbler 地图时出现异常。似乎是并发异常导致无效的数组访问,但由于 Skobbler 提供的代码存在问题,因此不确定如何最好地修复损坏的代码。

见标有“这里!!!”的行 在下面的代码中:

文件:SKTNavigationManager.m

- (void)routingService:(SKRoutingService *)routingService didFinishRouteCalculationWithInfo:(SKRouteInformation *)routeInformation {
    dispatch_async(dispatch_get_main_queue(), ^{
       __block BOOL routeExists = NO;
       [_calculatedRoutes enumerateObjectsUsingBlock:^(SKRouteInformation *obj, NSUInteger idx, BOOL *stop) {
            if (routeInformation.routeID == obj.routeID) {
                routeExists = YES;
                *stop = YES;
            }
        }];

       if (!routeInformation.corridorIsDownloaded || routeExists || _calculatedRoutes.count == _configuration.numberOfRoutes) {
           return;
       }

       //are we still calculating the routes?
       if ([self hasState:SKTNavigationStateCalculatingRoute]) {
           [_calculatedRoutes addObject:routeInformation];

           //stop progress for the calculated route
           SKTRouteProgressView *progressVIew = _mainView.calculatingRouteView.progressViews[_calculatedRoutes.count - 1]; // HERE!!!
           [progressVIew startProgress];

           //show the info for the calculated route
           [_mainView.calculatingRouteView showInfoViewAtIndex:_calculatedRoutes.count - 1];
           [self updateCalculatedRouteInformationAtIndex:_calculatedRoutes.count - 1];

           //start progress for next route if needed
           if (_calculatedRoutes.count < _mainView.calculatingRouteView.numberOfRoutes) {
               SKTRouteProgressView *progressVIew = _mainView.calculatingRouteView.progressViews[_calculatedRoutes.count];
               [progressVIew startProgress];
           }

           if (!_selectedRoute) {
               _selectedRoute = routeInformation;
               [SKRoutingService sharedInstance].mainRouteId = _selectedRoute.routeID;
               [self zoomOnSelectedRoute];
               _mainView.calculatingRouteView.selectedInfoIndex = 0;
               _mainView.calculatingRouteView.startButton.hidden = NO;
           }
       } else if ([self hasState:SKTNavigationStateRerouting]) { //nope, we're being rerouted
           _selectedRoute = routeInformation;
           _navigationInfo.currentDTA = _selectedRoute.distance;
           [self updateDTA];
           _navigationInfo.currentETA = _selectedRoute.estimatedTime;
           [self updateETA];
           [SKRoutingService sharedInstance].mainRouteId = _selectedRoute.routeID;
           [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(removeReroutingState) object:nil];
           [self performSelector:@selector(removeReroutingState) withObject:nil afterDelay:kMinReroutingDisplayTime];
       }
    });
}

报告的异常是...

8   libobjc.A.dylib - objc_exception_throw + 332 (objc-exception.mm:568)
9   CoreFoundation - [__NSArrayM objectAtIndex:] + 240 (NSArray.m:410)
10  MyApp -[SKTNavigationManager routingService:didFinishRouteCalculationWithInfo:]_block_invoke + 676 (SKTNavigationManager.m:463)

有任何想法吗?在从 progressViews 数组读取之前,我可以检查 _calculatedRoutes 的大小,但我遇到的问题是在访问两者的行之后还有其他代码。换句话说,我可以避免这条线,但我该如何修复该方法才能正常工作?

4

1 回答 1

1

SKTNavigationManager 中的代码(以及整个 SDKTools 项目中的代码)作为开放代码提供 - 它不是 SDK 本身的一部分,而是构成一些演示代码/帮助程序类,可以帮助您解决常见场景(构建简单的导航 UI,处理离线地图等)。

一些开发人员将此代码用作文档,其他开发人员在他们的项目中“按原样”使用它,其他开发人员从它开始并根据自己的喜好对其进行自定义。

在您的特殊情况下,我不确定您是如何到达这种不一致状态的(使用 vanilla 代码,在演示项目中我无法复制) - 如果您认为自己有并发问题,请随时插入额外的检查或同步机制。

于 2016-07-19T06:29:44.943 回答