iPhone app launch times and Core Data migration

后端 未结 5 1546
有刺的猬
有刺的猬 2021-02-02 01:51

I have a Core Data application which I plan to update with a new schema. The lightweight migration seems to work, but it takes time proportional to the amount of data in the dat

5条回答
  •  不思量自难忘°
    2021-02-02 02:24

    Here is an outline of an approach similar to what ohhorob describes. The difference is that I just display an animated "Upgrading..." HUD rather than a more informative progress bar.

    The key point is that nothing tries to access Core Data until the migration has had a chance to do its thing. Therefore, I move all the remaining launch code (including the setting of the rootViewController) that could potentially touch Core Data into a separate method. I then call this method after the migration has completed, or immediately if no migration is required. That looks like this:

    -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        [self.window makeKeyAndVisible];
    
        if ([MyManagedObject doesRequireMigration]) { // -doesRequireMigration is a method in my RHManagedObject Core Data framework
            [SVProgressHUD showWithStatus:NSLocalizedString(@"Upgrading...", nil) maskType:SVProgressHUDMaskTypeGradient];
    
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    
                // do your migration here
    
                dispatch_async(dispatch_get_main_queue(), ^{
                    [SVProgressHUD showSuccessWithStatus:NSLocalizedString(@"Success!",nil)];
                    [self postApplication:application didFinishLaunchingWithOptions:launchOptions];
                });
            });
    
        } else {
            [self postApplication:application didFinishLaunchingWithOptions:launchOptions];
        }
    
        return YES;
    }
    
    -(void)postApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        self.window.rootViewController = ....
    
        // anything else you want to run at launch
    }
    

    This approach should play nice with the watchdog that monitors startup times since the migration will take place off the main thread.

提交回复
热议问题