GMSThreadException' 原因:'API 方法必须从主线程调用'

Posted

技术标签:

【中文标题】GMSThreadException\' 原因:\'API 方法必须从主线程调用\'【英文标题】: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;
         );

     ];

);

【问题讨论】:

【参考方案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];
        
    );

【讨论】:

以上是关于GMSThreadException' 原因:'API 方法必须从主线程调用'的主要内容,如果未能解决你的问题,请参考以下文章

常见内存泄漏引起原因

SQL Server死锁产生原因及解决办法

Cacheable不生效的原因——方法内调用

MySQL死锁原因分析

右浮动div换行现象的原因

短路的原因与危害有哪些