iOS9 故事板什么是未处理的操作 (handleNonLaunchSpecificActions)?

iOS9 storyboard what is unhandled action (handleNonLaunchSpecificActions)?

我注意到当 运行 我的应用程序在 iOS 9 上使用故事板时,控制台中弹出以下错误。我正在使用 xCode7。这是我需要关心的事情吗?

-[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion:] ** unhandled action -> <FBSSceneSnapshotAction: 0x176bfb20> {
    handler = remote;
    info = <BSSettings: 0x176a5d90> {
        (1) = 5;
    };
}

AFAIK,上面的信息与屏幕快照期间的 iOS 有关(我想是双击主页多任务相关行为)。我深入研究了我的应用程序,似乎它没有任何副作用。您现在可以安全地忽略它。

您可以使用以下 gist simple category 来测试自己对上述函数的调用:

我已经弄明白了,当您在 .h 或 .m 文件中声明了 IBAction 方法但您没有将它绑定到任何控件时,就会发生这种情况。

.m 示例:

- (IBAction)click:(id)sender{
}

但未将此方法分配给故事板中的任何控件。

还没有找出为什么它会在我的应用程序中发生,但至少你可以捕获异常,如果你想阻止它在你的日志窗格中弹出的话。这不是一个解决方案,但它可能会让您更深入地了解为什么它会通过检查 catch 中传递的任何参数而快乐。

swift 2 个版本:

import UIKit

extension UIApplication {
    func _handleNonLaunchSpecificActions(arg1: AnyObject, forScene arg2: AnyObject, withTransitionContext arg3: AnyObject, completion completionHandler: () -> Void) {
        //whatever you want to do in this catch
        print("handleNonLaunchSpecificActions catched")
    }
}

您的代码没有任何问题。这是 Apple 内部的日志消息,您应该提交有关它的雷达。

有两个提示表明这是可能Apple的代码:

  1. 方法名称前导的下划线 _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion 是一种约定,表明该方法是 private/internal 到它声明的 class。(参见 this comment.)

  2. 有理由猜测 FBSSceneSnapshotAction 中的两个字母前缀是 FrontBoard 的 shorthand,根据 Rene Ritchie 在“iOS 9 wish-list: Guest Mode" 中的一部分与启动应用程序相关的整个软件系列:

With iOS 8, Apple refactored its system manager, SpringBoard, into several smaller, more focused components. In addition to BackBoard, which was already spun off to handle background tasks, they added Frontboard for foreground tasks. They also added PreBoard to handle the Lock screen under secure, encrypted conditions. [...]

我不知道 BSSettings 中的 BS 前缀是干什么用的,但是

BS 对于 BackBoard Settings 是 shorthand,对此日志消息的分析表明这不是您所做的任何事情,您应该提交一份雷达,其中包含重现该错误的步骤记录消息。

如果您想尝试获取堆栈跟踪,可以实施 。有些人会争辩说覆盖 private API 是个坏主意,但在这种情况下,临时注入以获取堆栈跟踪不会太有害。

编辑:

但是,我们还是想知道这个动作是什么。所以我在 -[UIApplication _handleNonLaunchSpecificActions:forScene:withTransitionContext:completion] 上设置了一个断点并开始打印出寄存器值并找到了一个名为 FBSceneImpl 的 class,它包含关于我的应用程序的一大堆信息:

我们可以找出接下来调用的是哪个私有方法(存储在程序计数器,指令指针,寄存器15。)

我试图找到日志中引用的未处理的 FBSceneSnapshotAction,但没有找到。然后,我子classed UIApplication,并覆盖_handleNonLaunchSpecificActions:forScene:withTransitionContext:completion。现在我可以直接了解这个动作了,但我们仍然不知道它是什么。

然后,我又看了看FBSceneSnapshotAction。结果它有一个名为 BSAction.

的 superclass

然后我写了 a tool similar to RuntimeBrowser 并查找了 BSAction 的所有子classes。事实证明,其中有很多:

我们拥有的两个方法名称(一个来自日志,一个来自设备上的程序计数器)表明这些操作在幕后用于在系统中传递操作。

一些操作可能会发送到应用程序委托的回调,而其他操作则在内部处理。

这里发生的事情是有一个动作没有被正确处理并且系统注意到了它。显然,我们不应该看到它。