生产应用程序中的 Swift 断言行为

问题描述 投票:0回答:5

我正在阅读 Swift 电子书中的断言部分,看起来断言的工作方式与 Objective-C 的对应部分非常相似。但是,在文档中我找不到任何有关作为生产应用程序运行时运行时行为的信息。 Objective-C 的

NSAssert
承诺永远不会因断言失败而终止生产应用程序。 Swift 中也是同样的情况吗?

ios objective-c xcode assert swift
5个回答
19
投票

根据苹果在其文档中使用的语言,我想说断言在生产环境中被忽略。

如果您的代码在调试中运行时触发断言 环境,例如当您在 Xcode 中构建并运行应用程序时,您可以 准确查看无效状态发生的位置并查询其状态 触发断言时您的应用程序。一个断言 还可以让您提供有关其性质的合适的调试消息 断言。

在“注释”块中:

断言会导致您的应用程序终止,并且不能替代 以不太可能出现无效条件的方式设计代码 出现。尽管如此,在条件无效的情况下 可能的话,断言是确保这种情况的有效方法 在开发过程中,在您之前,会突出显示并注意到条件 应用程序已发布。


12
投票
调试和发布之间的区别是编译器参数之间的区别。最可能的答案是会有一些特殊的编译器设置(类似于Java中的

-ea

)。

编辑 Swift 编译器有一个名为
-assert-config

 的参数

-assert-config 指定assert_configuration 替换。可能的值为“调试”、“发布”、“替换”。

Release

中,断言被忽略。不确定 
Debug
Replacement
 之间的区别。

enter image description here


6
投票
检查您的

Optimization Level

 并确保它不是用于发布配置的 
Onone
。请参阅我的笔记
https://github.com/onmyway133/blog/issues/39


3
投票
断言与先决条件一起记录在 Swift 标准库文档中。

    调试 -> 断言失败时停止。
  • 发布 -> 忽略断言进行编译
  • 发布和“禁用安全检查”-> 假设所有断言语句都是事实陈述和对编译器的提示,以便只有在断言失败的情况下才可以删除后面和前面的代码。这意味着如果您通过代码遵循断言来处理异常情况,则它可能会被忽略。如果断言失败,则行为完全未定义。
我没有检查过,但“禁用安全检查”可能与 @Sulthan 提到的 -assert-config 替换相关。


0
投票
我想指出,虽然断言在生产代码中“应该”被忽略(基于优化级别,请参阅其他答案以获取更多详细信息),但有时却并非如此。早在 2018 年就有一份关于潜在编译器错误的报告

,其中一个断言被忽略,一个没有,恐怕我刚刚在 iOS 17.5 / Xcode 15.4 上遇到了类似的问题。 因此,例如,如果您在生产中看到 EXC_BREAKPOINT 崩溃,并且

crash_info_entry_0

(至少在“Keys”下的 Firebase Crashlytics 中)包含您的

assertionFailure
消息,那么您并没有疯。
    

© www.soinside.com 2019 - 2024. All rights reserved.