【问题标题】:iOS unbalanced calls to applicationWillResignActive: and applicationDidBecomeActive:iOS 不平衡调用 applicationWillResignActive: 和 applicationDidBecomeActive:
【发布时间】:2014-01-27 16:52:12
【问题描述】:

当我的应用程序进入后台时,出于数据保护的原因,它必须模糊当前屏幕。屏幕内容不能在任务管理器窗口中看到,因此必须在应用退出之前完成模糊程序。每次 UI 更新时,必须在主循环上进行模糊处理。它只是在普通主视图上添加了一个模糊视图。但是,这需要一点时间才能完成,这就是问题所在。

按照 Apple 的建议,我从 applicationWillResignActive: 调用我的模糊例程。现在假设完成任务需要 0.2 秒。如果应用程序将在这么短的时间内重新激活,则不会调用 applicationDidBecomeActive: (这应该会再次使我的屏幕模糊,所以它会变得模糊)。

也许你认为在这么短的时间内“关闭”和“打开”一个应用程序不是正常的用户行为,但是想想点击屏幕的上边缘并向下移动一点,只是偶然的同时试图点击位于上边缘的按钮。这将在几分之一秒内激活通知中心。够了。

只是为了让这个问题变得透明,看看这个 AppDelegate,它将在控制台中发布不平衡的调用:


    @implementation UHAppDelegate

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        return YES;
    }

    - (void)applicationWillResignActive:(UIApplication *)application
    {
        NSLog(@"applicationWillResignActive - performing some tasks..."); 

        // let the main loop do some work...
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.2]];
    }

    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
    }

    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
    }

    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        NSLog(@"applicationDidBecomeActive");
    }

    - (void)applicationWillTerminate:(UIApplication *)application
    {
    }

    @end

在这种情况下如何实现对 applicationWillResignActive: 和 applicationDidBecomeActive: 的调用次数达到平衡...?

非常感谢您的帮助 乌多

【问题讨论】:

  • 上面写的你的 applicationWillResignActive 什么都不做?
  • 确实如此 - 它在控制台中发布一条注释并阻塞主循环 0.2 秒,就像主循环上的其他方法调用一样。
  • 如果您以正常速度执行通知中心的“下拉”并让它再次向上翻转,您将获得平衡的通话记录(“applicationWillResignActive - 执行某些任务”,然后“翻转”:“applicationDidBecomeActive”)。但是,如果您只是在屏幕顶部快速“点击并向下翻转/向上翻转”,则只会出现“applicationWillResignActive - 执行某些任务”,尽管该应用已再次处于活动状态)
  • This chart 应该会有所帮助。但如果你说的是真的,它可能需要一些更新。
  • 是的,如果应用程序仍未从 applicationWillEnterBackground 返回,iOS 似乎会放弃方法调用。

标签: ios iphone objective-c uikit uiapplicationdelegate


【解决方案1】:

经过一些测试,我意识到可能会有一些妥协。

似乎 applicationDidBecomeActive: 只与 applicationDidEnterBackground: 平衡

在我的情况下,这意味着模糊应该在后一种方法中进行。归根结底,这意味着如果用户通过调用通知中心或调用任务管理器“离开”我的应用程序,屏幕不会模糊。然而,关于数据安全,这不应该是一个重要的问题,因为很明显只有有权访问我的应用程序的用户才能执行这些步骤。

当应用程序通过单击 HOME 离开时,进入待机状态或通过任务管理器更改前台应用程序,applicationDidEnterBackground: 被调用,经过一些测试,似乎从操作系统获得了足够的时间来执行模糊在主循环上。

但是,如果你坚持原来的问题,这仍然没有解决。

【讨论】:

    【解决方案2】:

    如果应用程序在 -applicationWillResignActive() 方法完成之前再次“变为活动”,那么它可能永远不会完全退出活动状态,因此它可能不会触发对 -applicationDidBecomeActive() 的调用,因为活动状态可能根本没有改变。

    我会试试这个:

    1) 创建一个名为“showingBlur”的布尔值作为应用程序委托的成员,并在 -applicationDidFinishLaunching 方法中将其设置为 NO。

    2) 在 -applicationWillResignActive() 中,在开始 UI 更新之前,将“showingBlur”设置为 YES。

    3) 在 applicationWillEnterForeground() 中,检查布尔值,如果为真,则移除模糊视图并将其设置为假。

    或者这个:

    1) 当你制作你的模糊视图时,还要创建一个前景计时器,它会在第一次触发时删除它自己的模糊视图。这样,当您创建计时器时,您会立即将应用程序置于后台,因此它不会触发。但是,一旦您打开应用程序,它就会触发、删除自身并移除模糊视图。

    希望这会有所帮助!

    【讨论】:

    • 问题是 applicationWillEnterForeground() 也没有被调用。该应用程序根本没有关于它将再次激活这一事实的信息。 - 会尝试你的第二个想法!
    • 尝试了计时器的想法 - 很抱歉,即使应用程序已经进入后台,计时器也会触发。
    猜你喜欢
    • 2014-11-20
    • 2011-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-09
    相关资源
    最近更新 更多