ios – application:didFinishLaunchingWithOptions:在创建目标控制器之前触发通知

你好,
我正在写一个应用程序,当应用本地通知来打开它时,应用UI更新和内部状态更改.我正在使用故事板,我设置了我的主视图控制器来观察状态变化:
- (void)viewDidLoad
{
    [super viewDidLoad];
    // ...
    [[NSNotificationCenter defaultCenter] addobserver:self selector:@selector(resumeByNotification:) name:@"Resume" object:nil];
}

在我的应用程序委托我有这个:

- (void)application:(UIApplication *)application didReceivelocalnotification:(UIlocalnotification *)notification
{
    if (application.applicationState == UIApplicationStateInactive)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:notification.userInfo];
    }
}

这样做很好:如果应用程序在后台运行,则视图控制器将拦截通知并作出相应的反应. (如果应用程序在前台运行,则会被忽略,因为该UI正在被直接使用.)

当应用程序被杀死并收到通知时,会出现问题.我已经在didFinishLaunchingWithOptions方法中写过这个,使得手机作为一个快速的调试技术发生振动:),我得到通知

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIlocalnotification *localnotification = launchOptions[UIApplicationLaunchOptionslocalnotificationKey];
    if (localnotification)
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:localnotification.userInfo];
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    }

    return YES;
}

电话DOES振动,所以通知在那里,但它似乎没有触发观察者.我想这是因为view controller的didViewLoad方法还没有被调用.我不知道如何工作.我想我可以使用UIStoryboard的instantiateViewControllerWithIdentifier:方法,以确保视图控制器实际上在那里,但是我不会得到一个“额外”的实例,除了最终将被故事板自己的生命周期实例化?从课堂参考文献中的说法来看,这不完全是为了做这样的事情.

在这里缺少一些非常明显的东西吗?其实我的做法是正确的吗?

谢谢!

解决方法

视图控制器不会加载其视图,直到有人要求它的视图.在发布时,通常会在应用程序之后发生:didFinishLaunchingWithOptions:returns.

你可能会想知道为什么.答案是您可以在启动时实例化几个视图控制器,其中一些是隐藏的.例如,如果您的窗口的根视图控制器是UINavigationController,则可以使用一组视图控制器(用户最后一次运行应用程序的堆栈)来加载导航控制器.只有这个堆栈的顶视图控制器是可见的,所以不需要加载其他视图控制器的视图.系统等待直到应用程序:didFinishLaunchingWithOptions:在加载任何视图之前返回,以便只加载必要的视图.

因此,解决问题的一种方法只是要求视图控制器查看它,从而强制加载它.如果您的视图控制器是窗口的根视图控制器,您可以这样做:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    UIlocalnotification *localnotification = launchOptions[UIApplicationLaunchOptionslocalnotificationKey];
    if (localnotification) {
        [[self.window rootViewController] view];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"Resume" object:self userInfo:localnotification.userInfo];
        AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
    }

    return YES;
}

不同的解决方法是在视图控制器的initWithCoder:方法中开始观察通知

- (id)initWithCoder:(NSCoder *)aDecoder {
    if (self = [super initWithCoder:aDecoder]) {
        [[NSNotificationCenter defaultCenter] addobserver:self selector:@selector(resumeByNotification:) name:@"Resume" object:nil];
    }
    return self;
}

当视图控制器从MainStoryboard实例化时发生,这是在应用程序之前发生的:didFinishLaunchingWithOptions:message.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...