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

编程入门 行业动态 更新时间:2024-10-28 18:33:31
本文介绍了application:didFinishLaunchingWithOptions:创建目标控制器之前触发通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

你好, 我正在编写一个应用程序,当使用本地通知打开它时,应使用UI更新和内部状态更改进行响应.我正在使用情节提要,并且已经设置了主视图控制器来观察状态变化:

Hello, I am writing an app that should respond with an UI update and an internal status change when a local notifcation is used to open it. I am using storyboards and I have set up my main view controller to observe status changes:

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

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

In my app delegate I have this:

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

这很好用:如果应用程序在后台运行,则视图控制器将拦截通知并做出相应的反应. (如果应用程序在前台运行,则将被忽略,因为将直接处理用户界面.)

And this works just fine: if the app is running in the background, the view controller will intercept the notification and react accordingly. (If the app is running in the foreground, it's ignored because the UI is being taken care of directly.)

当应用程序被杀死并收到通知时,会出现问题.我已经在didFinishLaunchingWithOptions方法中编写了此代码,使手机作为一种快速调试技术:)振动,我 do 收到了通知:

The problem arises when the app has been killed and the notification is received. I have written this in the didFinishLaunchingWithOptions method, making the phone vibrate as a quick debug technique :), and I do get the notification:

- (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:方法来确保视图控制器确实存在,但是除了最终将由情节提要的自身生命周期实例化的那个实例之外,我是否会得到它的额外"实例? ?从类参考文档上的内容来看,这并非完全意味着要做这种事情.

The phone DOES vibrate so the notification IS there, but it doesn't seem to trigger the observer. I suppose that this is because the view controller's didViewLoad method hasn't been called yet. I am not sure how to work this around. I suppose I could use UIStoryboard's instantiateViewControllerWithIdentifier: method to make sure the view controller is actually there, but wouldn't I be getting an "extra" instance of it, in addition to the one that will eventually be instantiated by the storyboard's own life cycle? Judging from what the on the class reference documentation says, it's not exactly meant to do this kind of thing.

我在这里错过了很明显的东西吗?实际上,对于这种情况,我的方法正确吗?

Am I missing something very obvious here? In fact, is my approach the correct one for this kind of situation?

谢谢!

推荐答案

在有人向其询问其视图之前,视图控制器不会加载其视图.在启动时,通常会在application:didFinishLaunchingWithOptions:返回之后发生.

The view controller doesn't load its view until something asks it for its view. At launch time, that normally happens after application:didFinishLaunchingWithOptions: returns.

您可能想知道为什么.答案是,您可能在启动时实例化了多个视图控制器,其中有些是隐藏的.例如,如果窗口的根视图控制器是UINavigationController,则可以向视图控制器加载一堆视图控制器(用户上次运行该应用程序时推入的堆栈).仅此堆栈的顶视图控制器可见,因此无需加载其他视图控制器的视图.系统等待直到application:didFinishLaunchingWithOptions:返回,然后再加载任何视图,以便仅加载必要的视图.

You might wonder why. The answer is that you might instantiate several view controllers at launch time, some of which are hidden. For example, if your window's root view controller is a UINavigationController, you might load the navigation controller with a stack of view controllers (the stack that the user had pushed the last time the app ran). Only the top view controller of this stack is visible, so there's no need to load the views of the other view controllers. The system waits until application:didFinishLaunchingWithOptions: returns before loading any views so that only the necessary views will be loaded.

因此,解决问题的一种方法就是简单地向视图控制器索要其视图,从而强制其加载.如果您的视图控制器是窗口的根视图控制器,则可以通过以下方式做到这一点:

So one way to work around your problem would simply be to ask the view controller for its view, thus forcing it to load. If your view controller is the window's root view controller, you can do it this way:

- (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:方法中观察通知:

A different workaround would be to start observing the notification in your view controller's initWithCoder: method:

- (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:消息之前.

This is called when the view controller is instantiated from the MainStoryboard, which happens before the application:didFinishLaunchingWithOptions: message.

更多推荐

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

本文发布于:2023-06-11 03:39:31,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/625904.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:控制器   目标   通知   application   didFinishLaunchingWithOptions

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!