![](/img/trans.png)
[英]application:didFinishLaunchingWithOptions loading before viewDidLoad
[英]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.