在两个嵌套子类中调用 super.viewDidLoad() 时,我遇到了 Swift 的无限循环
Posted
技术标签:
【中文标题】在两个嵌套子类中调用 super.viewDidLoad() 时,我遇到了 Swift 的无限循环【英文标题】:I'm getting an infinite loop with Swift when calling super.viewDidLoad() in two nested subclasses 【发布时间】:2015-01-12 09:18:22 【问题描述】:我正在开发一个用 Swift 编写的 ios 应用程序。我有一个 UITabBarController 的子类,然后是一个嵌套的子类:
class HWTabBarController: UITabBarController
override func viewDidLoad()
super.viewDidLoad()
...
class MainTabBarController: HWTabBarController
override func viewDidLoad()
super.viewDidLoad()
...
这在 iOS 模拟器中运行良好,甚至在我在 iPhone 上调试应用程序时也是如此。 但是当我将应用程序存档并使用 TestFlight 将其发送到我的手机时,它会崩溃。
我的崩溃日志充满了这个无限循环:
22 HDWR 0x00145e10 @objc HDWR.MainTabBarController.viewDidLoad (HDWR.MainTabBarController)() -> () (MainTabBarController.swift:16)
23 HDWR 0x00262867 NRMA__voidParamHandler
24 HDWR 0x0014ea00 HDWR.HWTabBarController.viewDidLoad (HDWR.HWTabBarController)() -> () (HWTabBarController.swift:24)
25 HDWR 0x00145e10 @objc HDWR.MainTabBarController.viewDidLoad (HDWR.MainTabBarController)() -> () (MainTabBarController.swift:16)
26 HDWR 0x00262867 NRMA__voidParamHandler
27 HDWR 0x0014ea00 HDWR.HWTabBarController.viewDidLoad (HDWR.HWTabBarController)() -> () (HWTabBarController.swift:24)
28 HDWR 0x00145e10 @objc HDWR.MainTabBarController.viewDidLoad (HDWR.MainTabBarController)() -> () (MainTabBarController.swift:16)
29 HDWR 0x00262867 NRMA__voidParamHandler
30 HDWR 0x0014ea00 HDWR.HWTabBarController.viewDidLoad (HDWR.HWTabBarController)() -> () (HWTabBarController.swift:24)
31 HDWR 0x00145e10 @objc HDWR.MainTabBarController.viewDidLoad (HDWR.MainTabBarController)() -> () (MainTabBarController.swift:16)
32 HDWR 0x00262867 NRMA__voidParamHandler
33 HDWR 0x0014ea00 HDWR.HWTabBarController.viewDidLoad (HDWR.HWTabBarController)() -> () (HWTabBarController.swift:24)
voidParamHandler
指令是什么,为什么它会返回到MainTabBarController.viewDidLoad
?
我在这里做错了吗?或者这是 Swift 中的一个错误?
【问题讨论】:
类是如何实例化的? 正常情况下:let mainController = MainTabBarController()
.
您是否尝试删除应用程序并清理 Xcode 上的构建并重新安装?有时这可以解决随机问题。
是的,已经尝试过了。我实际上正在重新讨论这个问题,因为无限循环出现在不同的地方,那里还有 2 个级别的子类化并调用 super.viewDidLoad()
我尝试使用测试应用程序重现此内容,但无法使其崩溃!不过,这里是 repo:github.com/ndbroadbent/SwiftSuperCrash 如果我能让它在我的手机上崩溃,我会更新。
【参考方案1】:
您是否在您的应用中使用New Relic? (我从所有这些NRMA__voidParamHandler
引用中猜测你是。)我遇到了这个确切的问题。我禁用了 New Relic SDK 并且从 Testflight 下载的构建停止崩溃。我还没有报告错误,但你/我/我们可能应该报告。
【讨论】:
就是这样!我应该意识到 NRMA 与 New Relic 有关。我已经更新了我的 POC 存储库,它现在重现了这个崩溃:github.com/ndbroadbent/SwiftSuperCrash 非常感谢!! 我在 New Relic 论坛上报告了一个错误:discuss.newrelic.com/t/… 对于正在阅读本文的任何人,请查看 Bryce Buchanan 的答案,将dynamic
添加到 New Relic 仪器解决此问题的方法中。【参考方案2】:
添加了 swift 后,objective-c 所拥有的所有甜蜜的动态函数查找功能都被取消了。要恢复该功能,您需要将“动态”声明标志添加到 New Relic 仪器的所有方法中。
像这样:
class HWTabBarController: UITabBarController
override dynamic func viewDidLoad()
super.viewDidLoad()
...
class MainTabBarController: HWTabBarController
override dynamic func viewDidLoad()
super.viewDidLoad()
...
更多详细信息,包括其中包含哪些功能,请点击此处:https://docs.newrelic.com/docs/mobile-monitoring/new-relic-mobile/getting-started/enabling-swift-interaction-traces
【讨论】:
这可以连接到任何 Obj-C swizzles 吗?【参考方案3】:我刚刚下载了 repo,在我自己的个人资料上签名,一切似乎都按照你的程序运行。没有无限循环,没有崩溃。这也是通过试飞。这使我相信您的系统某处存在一些错误。我建议做一些事情...
-
清理构建 cmd+alt+shift+k && 删除手机上的应用程序。
关闭 Xcode,然后删除您的派生数据。 (如果您还没有完成此操作,我会详细说明如何操作。)
如果可行,将其注册为试飞中的新应用程序。
我的想法是,当您删除派生数据时它会有所帮助,但我会这样做只是为了让您知道一切都是干净的。同样,我在任何阶段都没有遇到这个问题:模拟器,直接从 Xcode 安装或通过 Test Flight 下载。
还要确保捆绑包 ID 已正确注册,并且在 Test Flight 的服务器端一切正常。我无法想象为什么它会导致循环,但这是一种奇怪的情况,所以让我们看看会发生什么。 :^)
【讨论】:
对不起,我在上面试图提到我也无法让测试应用程序崩溃,所以它只发生在我们的真实应用程序上。我将继续尝试将更多代码添加到示例应用程序中,看看我是否可以重现它。感谢您对此进行调查! @nathan.f77 你能发布你在程序中有任何for
或while
循环的代码吗? viewDidLoad
只能调用一次。
嗨,斯科特,再次感谢您的宝贵时间!另一位用户帮助我弄清楚这是由 New Relic Agent 试图分析我的代码引起的:***.com/a/27416135/304706
@nathan.f77 不用担心,很高兴你明白了!以上是关于在两个嵌套子类中调用 super.viewDidLoad() 时,我遇到了 Swift 的无限循环的主要内容,如果未能解决你的问题,请参考以下文章