UIWindow的makeKeyAndVisible和后台任务

时间:2014-09-05 08:39:14

标签: ios ios7 uiwindow

我已将后台任务功能添加到我的应用程序中。这是我的应用代表

// AppDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
    [self.window setBackgroundColor:[UIColor blackColor]];

    if (application.applicationState != UIApplicationStateBackground) {        
        // Application is launch in because user tap the app icon or from springboard

        if ([application respondsToSelector:@selector(setMinimumBackgroundFetchInterval:)]) {
            [application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
        }
    } else {
        // Application is launch in background mode
    }

    RootViewController *rootViewController = [[RootViewController alloc] initByDevice];
    [self.window setRootViewController:rootViewController];
    [self.window makeKeyAndVisible];

    return YES;
}

- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {

    [[DataManager instance] updateDataWithMaxAttempt:5 block:^(BOOL success, NSArray *newData) {
        if (success) {
            if ([newData count] > 0) {
                completionHandler(UIBackgroundFetchResultNewData);
            } else {
                completionHandler(UIBackgroundFetchResultNoData);
            }
        } else {
            completionHandler(UIBackgroundFetchResultNoData);
        }
    }];
}

这是我的根视图控制器

// RootViewController.m

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    NSLog(@"Did appear");
    // Do something that I want it to happen only when the application is visible to user
}

当用户点按应用图标时,应用程序就像我预期的那样工作。我看到“已经出现”在控制台中,事情正如我预期的那样发生。

但是当应用程序唤醒执行后台任务(对用户不可见)时RootViewController's viewDidAppear仍会因此行而被调用

[self.window makeKeyAndVisible];

通过调用makeKeyAndVisible,它使RootViewController可见,即使它只是为后台任务清醒。要解决此问题,我必须将此行移至applicationDidBecomeActive

- (void)applicationDidBecomeActive:(UIApplication *)application {
    [self.window makeKeyAndVisible];
}

因此,RootViewController's viewDidAppear仅在应用程序位于前台(用户可见)时才会调用。但是,我担心的是,当应用程序在设备内存中时(活动或非活动)applicationDidBecomeActive将被多次调用。

  • 用户启动应用
  • 应用程序从跳板再次激活
  • 设备解锁
  • 结束通话

如果我在应用程序生命周期中多次致电UIWindow's makeKeyAndVisible,是否有任何问题?

1 个答案:

答案 0 :(得分:1)

您可以轻松确保makeKeyAndVisible仅发生一次:换行。

if (!self.window.keyWindow) {
    [self.window makeKeyAndVisible;
} else if (self.window.hidden) {
    self.window.hidden = NO;
}