You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

主线程访问布局引擎后后台线程修改致Map加载崩溃求助

解决Tab Bar切换时MKMapView多次加载崩溃问题

崩溃报错:

Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.

This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.

问题核心:你仅将弹窗逻辑切换到了主线程,但修改MKMapView的核心操作(设置区域、添加标注)仍在后台线程执行——NSURLConnection sendAsynchronousRequest使用了自定义的NSOperationQueue,其completionHandler会在这个后台队列运行,而UIKit组件(包括MKMapView)的所有操作必须在主线程执行。

修复方案

将所有涉及UI/地图修改的代码,包括设置地图区域、添加标注的逻辑,全部包裹到dispatch_async(dispatch_get_main_queue(), ^{ ... })块中,确保任何UI相关操作都不在后台线程执行。

修改后的代码

-(void)showGoMap{
    // 若showGoMap在后台线程调用,这行也需移到主线程,避免潜在隐患
    dispatch_async(dispatch_get_main_queue(), ^{
        self.mapView.hidden = NO;
    });
    
    int randomIndex = arc4random() % [arr_OfCountryCode count];
    
    NSString *urlString = [NSString stringWithFormat:@"https://maps.googleapis.com/maps/api/geocode/json?address=%@&sensor=false,+CA&key=MY_API_KEY",
                           [arr_OfCountryCode objectAtIndex:randomIndex]];
    
    NSURL *url = [[NSURL alloc] initWithString:urlString];
    NSLog(@"Sending request");
    [NSURLConnection sendAsynchronousRequest:[[NSURLRequest alloc] initWithURL:url] queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
        NSLog(@"Response Received");
        if (error) {
            NSLog(@"%@",error.description);
            return;
        }
        
        NSDictionary *jsonObject=[NSJSONSerialization
                                  JSONObjectWithData:data
                                  options:NSJSONReadingMutableLeaves
                                  error:nil];
        
        NSLog(@"Data: %@", jsonObject);
        NSString *responseStatus = [[jsonObject objectForKey:@"status"] lowercaseString];
        NSLog(@"Status: %@", responseStatus);
        
        if (![responseStatus isEqualToString:@"ok"]) {
            dispatch_async(dispatch_get_main_queue(),
                           ^{
                               UIAlertController *limitExceededAlert = [UIAlertController alertControllerWithTitle:@"Not working This Time!" message:@"Try Again" preferredStyle:UIAlertControllerStyleAlert];
                               UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"I'll Try Again Shortly" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                               }];
                               [limitExceededAlert addAction:okAction];
                               [self presentViewController:limitExceededAlert animated:true completion:nil];
                           });
            return;
        }
        
        NSDictionary *places = [[[[jsonObject objectForKey:@"results"] objectAtIndex:0] objectForKey:@"geometry"] objectForKey:@"location"];
        NSDictionary *locations = [[[jsonObject objectForKey:@"results"] objectAtIndex:0] objectForKey:@"address_components"];
        
        float lat = [[places objectForKey:@"lat"] floatValue];
        float lon = [[places objectForKey:@"lng"] floatValue];
        
        MKCoordinateRegion region;
        MKCoordinateSpan span;
        span.latitudeDelta = 0.50;
        span.longitudeDelta = 0.50;
        
        CLLocationCoordinate2D location = CLLocationCoordinate2DMake(lat, lon);
        region.span = span;
        region.center = location;
        
        NSString *str_Title = [[locations valueForKey:@"long_name"] objectAtIndex:0];
        NSString *str_Short = [[locations valueForKey:@"short_name"] objectAtIndex:0];
        
        MKPointAnnotation *point = [[MKPointAnnotation alloc] init];
        point.coordinate = location;
        point.title = str_Title;
        point.subtitle = str_Short;
        
        // 所有地图相关操作移到主线程执行
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.mk_MapView setRegion:region animated:YES];
            [self.mk_MapView addAnnotation:point];
        });
    }];
}

内容的提问来源于stack exchange,提问作者DannyRoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:15:45