【问题标题】:GMSThreadException' reason: 'The API method must be called from the main thread'GMSThreadException' 原因:'API 方法必须从主线程调用'
【发布时间】:2017-03-08 07:47:19
【问题描述】:
由于未捕获的异常 GMSThreadException,我在使用谷歌 API 终止应用程序绘制折线时遇到此错误
-(void)drawRoute
{
dispatch_queue_t myQueue = dispatch_queue_create("My Queue",NULL);
dispatch_async(myQueue, ^{
[self fetchPolylineWithOrigin:origin destination:destination completionHandler:^(GMSPolyline *polyline)
{
dispatch_async(dispatch_get_main_queue(), ^{
// Update the UI
if(polyline)
polyline.map = mapView;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
});
}];
});
}
【问题讨论】:
标签:
ios
objective-c
iphone
multithreading
cocoa-touch
【解决方案1】:
在主线程上也使用 GMSPath 和 GMSPolyline 然后它应该可以工作。
【解决方案2】:
从您的错误消息看来,您似乎只能从主线程调用该 API 方法,请尝试使用:
-(void)drawRoute
{
dispatch_async(dispatch_get_main_queue(), ^{
[self fetchPolylineWithOrigin:origin destination:destination completionHandler:^(GMSPolyline *polyline)
{
// Update the UI
if(polyline)
polyline.map = mapView;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}];
});
}
这仍将允许您的代码在它消失时继续执行并执行此操作,因为它是异步的,但将其保留在主线程(队列)上。该方法具有完成处理程序这一事实表明它本身是异步的,也许您根本不需要在这里进行调度?
我敢打赌,你会没事的:
-(void)drawRoute
{
[self fetchPolylineWithOrigin:origin destination:destination completionHandler:^(GMSPolyline *polyline)
{
// Update the UI
if(polyline)
polyline.map = mapView;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}];
}
或者您之前是否遇到过性能问题?
【解决方案3】:
在我的情况下,需要在两个地方使用主线程
一个是...
__block GMSMapView *mapView;
dispatch_async(dispatch_get_main_queue(), ^{
// Create GMSMapView
mapView = [GMSMapView mapWithFrame:CGRectMake(1, 1, _subView.frame.size.width-2, _subView.frame.size.height-2) camera:camera];
mapView.myLocationEnabled = YES;
[_subView addSubview:mapView];
});
第二个是……
- (void)fetchPolylineWithOrigin:(CLLocation *)origin destination:(CLLocation *)destination completionHandler:(void (^)(GMSPolyline *))completionHandler {
// Code here ....
__block GMSPolyline *polyline = nil;
dispatch_async(dispatch_get_main_queue(), ^{ // Second main
if ([routesArray count] > 0) {
NSDictionary *routeDict = [routesArray objectAtIndex:0];
NSDictionary *routeOverviewPolyline = [routeDict objectForKey:@"overview_polyline"];
NSString *points = [routeOverviewPolyline objectForKey:@"points"];
GMSPath *path = [GMSPath pathFromEncodedPath:points];
polyline = [GMSPolyline polylineWithPath:path];
}
});
}