避免在 App Delegate 中重复执行代码

Posted

技术标签:

【中文标题】避免在 App Delegate 中重复执行代码【英文标题】:Avoid duplicate execution of code in App Delegate 【发布时间】:2015-02-03 14:17:57 【问题描述】:

我的 App Delegate 中有一段代码通知我的第一个 View Controller 用户想要立即显示某些内容:

- (void)notifyAppWithURL:(NSURL *)url 
    if(!url)
        return;
    
    NSDictionary *dict = [self parseQueryString:[url query]];
    NSString *host = [url host];
    [self notifyApp:host value:dict[@"id"]];


- (void)notifyApp:(NSString *)key value:(NSString *)value 
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;
    [[NSNotificationCenter defaultCenter] postNotificationName:@"ShowOnLoad" object:nil userInfo:@
                                                                                                   key : value
                                                                                                   ];

我从didReceiveRemoteNotificationopenURL 委托方法触发。这两个一切正常。

但是,如果应用程序关闭,并且调用此方法:

didFinishLaunchingWithOptions 和我打了同样的电话:

if(launchOptions[UIApplicationLaunchOptionsURLKey])
    [self notifyAppWithURL:launchOptions[UIApplicationLaunchOptionsURLKey]];

在里面,然后两个NSNotification 被发送到视图控制器。

两个问题:

如何在我的 App Delegate 中重复调用 notifyAppWithURL 来解决这个问题?

此外,是否有更好、更广泛的解决方案来处理来自用户的多个传入操作(然后触发一些其他操作)?

【问题讨论】:

【参考方案1】:

documentation for application:openURL:sourceApplication:annotation: 表示以下内容:

如果您的应用必须启动才能打开 URL,则应用首先调用 application:willFinishLaunchingWithOptions:application:didFinishLaunchingWithOptions: 方法,然后再调用此方法。

您收到第一个通知是因为您在application:didFinishLaunchingWithOptions: 中调用了notifyAppWithURL:,第二个是因为您在application:openURL:sourceApplication:annotation: 中调用了它。一个简单的解决方案是简单地删除application:didFinishLaunchingWithOptions: 中的调用。

就您的第二个问题而言,实际上并没有一种通用的方法来处理导致某些代码运行两次或更多次的多个操作。 dispatch_once 是确保代码块在整个过程中运行一次且仅运行一次的标准方法,但这显然不是您想要的。

【讨论】:

以上是关于避免在 App Delegate 中重复执行代码的主要内容,如果未能解决你的问题,请参考以下文章

App Delegate 的方法 willTerminate 啥时候执行?

解决重复点击onClick事件,多次触发问题

使用 TabBar 和 NavBar 在 App Delegate 中配置窗口

避免公共类中的代码重复

ios block和delegate的区别

无法在测试中将 App Delegate 强制转换为 App Delegate