【问题标题】:NSAssert works in debugger but the message is missing from console when run directly on deviceNSAssert 在调试器中工作,但直接在设备上运行时控制台中缺少消息
【发布时间】:2013-08-06 12:52:19
【问题描述】:

NSAssert 在运行调试器时在 Xcode 4(最高 4.6 包括在内)中运行良好。断言触发,你给它断点,然后它输出断言消息。

但是当在调试器外部运行时(在设备上调试构建),断言触发 - 但没有消息。

这使得断言毫无用处:你可以看到断言的行号,但程序员的详细信息已被擦除。

这是 Xcode 的问题吗?铿锵声/LLVM 问题?是设置错误的值吗?或者有什么解决方法?


示例代码:

NSAssert(FALSE, @"X was invalid: %i", x );

示例输出(控制台):

<Warning>: *** Assertion failure in -[myClass method:], myClass.m:124
<Notice>: Formulating crash report for process MyApp[82]

预期输出(控制台):

<Warning>: *** Assertion failure in -[myClass method:], myClass.m:124
<Warning>: *** "X was invalid: -435"
<Notice>: Formulating crash report for process MyApp[82]

注意:我只是猜测 Apple 会如何格式化断言消息。


更新:发现了问题。我原来的描述有误:

消息在调试器中运行时没有输出到控制台

【问题讨论】:

    标签: ios objective-c xcode llvm


    【解决方案1】:

    两个观察结果:

    1. NSAssert 仅用于调试目的。当您构建应用的发布版本时,NSAssert 什么都不做。

    2. 当您在设备上运行的应用程序的调试版本中使用 NSAssert 时(而不是通过调试器),消息在设备的控制台中,而不是在 Xcode 中。如果你去 Xcode 中的“Organizer”,选择“Devices”,选择你的设备并查看“Console”,你会在那里看到你的断言。

    例如,我在“断言测试”应用程序中输入了一行代码:

    NSAssert(FALSE, @"Assertion performed here");
    

    当我通过 Xcode 的 Organizer 查看设备的“控制台”时,我看到了:

    8 月 6 日 09:10:53 Rob-iPod amfid[200]:8 月 6 日 09:10:53 SecTrustEvaluate [叶 CriticalExtensions IssuerCommonName] 8 月 6 日 09:10:53 Rob-iPod 断言测试 [199]:*** -[ViewController viewDidLoad] 中的断言失败,/Users/rryan/Documents/Development/Xcode/Assertion Test/Assertion Test/ViewController.m:21 8 月 6 日 09:10:53 Rob-iPod 内核[0]:launchd[199] 内置配置文件:容器(沙盒) 8 月 6 日 09:10:53 Rob-iPod 内核[0]:launchd[199] 容器:/private/var/mobile/Applications/7A7A62EF-8CEC-4388-932D-5C02DE77B841(沙盒) 8 月 6 日 09:10:53 Rob-iPod 断言测试 [199]:*** 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“此处执行的断言” *** 首先抛出调用堆栈: (0x315592a3 0x391d797f 0x3155915d 0x31e2eab7 0x843f7 0x33380595 0x333c0d79 0x333bcaed 0x333fe1e9 0x333c183f 0x333b984b 0x33361c39 0x333616cd 0x3336111b 0x350535a3 0x350531d3 0x3152e173 0x3152e117 0x3152cf99 0x3149febd 0x3149fd49 0x333b8485 0x333b5301 0x84149 0x3960eb20) 8 月 6 日 09:10:54 Rob-iPod ReportCrash[201]:为进程断言测试制定崩溃报告 [199] 8 月 6 日 09:10:54 Rob-iPod com.apple.launchd[1] (UIKitApplication:com.robertmryan.Assertion-Test[0x7be0][199]) : (UIKitApplication:com.robertmryan.Assertion-Test[0x7be0])作业似乎已崩溃:中止陷阱:6 8 月 6 日 09:10:54 Rob-iPod backboardd[26]:应用程序 'UIKitApplication:com.robertmryan.Assertion-Test[0x7be0]' 异常退出,信号 6:中止陷阱:6 8 月 6 日 09:10:54 Rob-iPod ReportCrash[201]:libMobileGestalt copySystemVersionDictionaryValue:无法从系统版本字典中查找 ReleaseType 8 月 6 日 09:10:54 Rob-iPod ReportCrash[201]:将 crashreport 保存到 /var/mobile/Library/Logs/CrashReporter/Assertion Test_2013-08-06-091053_Rob-iPod.plist using uid: 0 gid: 0, synthesis_euid :501 例如:0

    如果您查看第五行,您将在那里看到断言消息。

    【讨论】:

    • 1.如原始问题所述,断言正在触发。显然,如果我禁用断言,我预计不会发生任何事情。 2.你的“第五行”在Xcode外部运行时从不出现,但在xcode内部运行时确实出现
    • 更具体地说:你的第 2 行和第 6 行显示给我,但你的第 5 行没有。
    • 如何在 Xcode 主窗口中查看控制台而不运行调试器?我认为这是不可能的
    • @Adam 正如我所说,转到 Xcode“Organizer”(从 Xcode 的“Window”菜单中选择“Organizer”),然后点击“Devices”...
    • 好的,没有区别。 Xcode 管理器有什么神奇之处?读什么不是 iOS 控制台?
    【解决方案2】:

    这是非常具体的情况......我没有意识到,但我们在应用程序中嵌入了 HockeyApp / QuincyKit。

    曲棍球似乎有一个讨厌的错误:

    1. 捕获 NSA 断言
    2. 允许他们崩溃
    3. 删除消息
    4. 删除日志记录
    5. ...向曲棍球网站上传任何内容

    所以...消息在调试器中可见,但仅在调试器变量中 - 我是个傻瓜,没有注意:它们没有出现在控制台中。


    需要明确:某些断言有时会出现在 Hockey 中(查看 Hockey 控制台),但大多数断言都默默地丢失了。出现 100% 的 App 崩溃,但只有大约 10% 的断言崩溃。

    【讨论】:

    • 非常好。虽然这无疑令人沮丧,但我可以理解曲棍球不费心处理这个问题的逻辑。他们在为报告生产崩溃而设计的框架中处理NSAssert 毫无意义,因为作为发布版本的生产代码无论如何都不应该有断言(NSAssert 是发布版本中的空操作)。但解开谜团是件好事!
    • 是的,但是 ... 有大量设备需要在调试版本上进行测试(20 多个物理设备 ... 这是一个复杂的产品)... 曲棍球有很大的潜力使开发更快(自动更新构建,自动报告到集中式数据库等)。我确信我们不是唯一尝试在调试版本中使用 Hockey 的人:)
    • 希望曲棍球 discussion forumssupport page 可以提供帮助。祝你好运。
    猜你喜欢
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    • 2013-10-24
    • 1970-01-01
    • 2019-05-07
    • 2014-07-03
    • 2016-10-21
    • 1970-01-01
    相关资源
    最近更新 更多