簡體   English   中英

application:didFinishLaunchingWithOptions:在創建目標控制器之前觸發通知

[英]application:didFinishLaunchingWithOptions: firing notification before destination controller is created

您好,我正在編寫一個應用程序,當使用本地通知打開它時,該應用程序應響應UI更新和內部狀態更改。 我正在使用故事板,我已經設置了我的主視圖控制器來觀察狀態變化:

- (void)viewDidLoad
{
    [super viewDidLoad];
    // ...
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeByNotification:) name:@"Resume" object:nil];
}

在我的app委托中,我有這個:

- (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;
}

電話會振動,因此通知就在那里,但它似乎沒有觸發觀察者。 我想這是因為尚未調用視圖控制器的didViewLoad方法。 我不知道如何解決這個問題。 我想我可以使用UIStoryboard的instantiateViewControllerWithIdentifier:方法來確保視圖控制器實際存在,但除了最終將由故事板自己的生命周期實例化之外,我不會得到它的“額外”實例。 ? 從課堂參考文獻中的內容來看,這並不意味着要做這種事情。

我錯過了一些非常明顯的東西嗎? 事實上,對於這種情況,我的方法是正確的嗎?

謝謝!

視圖控制器不會加載其視圖,直到有人詢問它的視圖。 在啟動時,通常在application:didFinishLaunchingWithOptions:之后發生application:didFinishLaunchingWithOptions:返回。

你可能想知道為什么。 答案是您可以在啟動時實例化多個視圖控制器,其中一些是隱藏的。 例如,如果窗口的根視圖控制器是UINavigationController ,則可以使用一堆視圖控制器(用戶上次運行應用程序時推送的堆棧)加載導航控制器。 只有該堆棧的頂視圖控制器可見,因此無需加載其他視圖控制器的視圖。 系統等待,直到application: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實例化視圖控制器時調用它,該操作在application:didFinishLaunchingWithOptions:之前發生application:didFinishLaunchingWithOptions: message。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM