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

Avoid duplicate execution of code in App Delegate

我的 App Delegate 中有一段代码通知我的第一个视图控制器用户希望立即显示一些内容:

- (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 委托方法触发。这两者一切正常。

不过,好像如果app关闭了,调用这个方法:

didFinishLaunchingWithOptions 和我打了同一个电话:

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

内部,然后两个 NSNotification 被发送到视图控制器。

两个问题:

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

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

documentation for application:openURL:sourceApplication:annotation: 表示如下:

If your app had to be launched to open the URL, the app calls the application:willFinishLaunchingWithOptions: and application:didFinishLaunchingWithOptions: methods first, followed by this method.

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

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