Occasionally iOS 6 MKMapView crashes in initWithFrame

拈花ヽ惹草 提交于 2019-11-28 16:52:23

We were having a similar problem when user's background our app just as we're popping up a window that includes a map subview. The crash seemed to be happening due to the map using an openGL call while we're backgrounded. We had to wrap the map subview creation in a check like the following:

UIApplicationState appState = [[UIApplication sharedApplication] applicationState];
    if( (appState != UIApplicationStateBackground) && (appState != UIApplicationStateInactive))
    {
        // Do map subview initialization...
    }
    else
    {
        self.attemptedToLoadMap = YES;
    }

We saved off the bool so that if the app comes back to the foreground we can add the subview in for display.

You have to do this anytime you're manipulating the map in a way that causes a re-draw operation (e.g., adding an annotation).

We found the cause of this in our app so I wanted to post the solution in case it would help anyone else. Our primary view controller monitors significant location changes when it is displayed and stops monitoring when it is hidden. Some number of our users experienced an unrelated crash on this screen, which left the app monitoring. When an app has registered for significant location change updates, iOS will actually launch the app into the background if it is not running to tell it about the new location. Since our app displays a map when it first comes up, this caused a crash. Apple support confirmed with us that there is a bug on 32 bit devices running iOS 8.x that may cause a crash if a MapView (or other OpenGL context) is updated while the app is in the background.

We changed our code so that if the app is launched due to a significant location change we immediately stop monitoring and throw an exception to crash the app. This is completely invisible to the user so they do not notice the crash, and it prevents further crashes from happening.

- (void)validateLaunchWithOptions:(NSDictionary *)launchOptions
{
    if (launchOptions[@"UIApplicationLaunchOptionsLocationKey"]) {
        // the app was launched due to a significant location change, which is not valid and causes crashes
        // prevent this from happening again by disabling significant location monitoring
        CLLocationManager *locationManager = [[CLLocationManager alloc] init];
        [locationManager stopMonitoringSignificantLocationChanges];

        // intentionally crashing the app here; it is not in a good state and it needs to be prevented from
        // getting to any code that would re-enable significant location monitoring
        @throw [NSException exceptionWithName:@"com.redacted.significantLocationLaunch"
                                       reason:@"app may not be launched due to significant location changes"
                                     userInfo:@{}];
    }
}

We saw thousands of this crash but were not able to duplicate it on our test devices until we figured out the cause. If you would like to duplicate it (and also confirm the fix), @throw an exception immediately after your app starts monitoring significant location changes. After the app crashes, go take a drive. As soon as your phone switches cell towers iOS will launch the app in the background and you will get the crash. We were able to get our hands on one of our users phones and inspect the crash logs. All of the crashes happened during her commute to and from work.

hunterhacker

I'm facing a similar stack trace. I noticed that in the console it is giving more detail on the actual problem: you can't use the GPU while in the background. The maps with iOS 5 were tile based so I assume didn't use the GPU, but the new maps in iOS 6 use vector graphics and thus the GPU. As a result, any map work that used to be in the background no longer can be.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!