Swift中的失败安全断言

卢西亚诺马里西

我通常在Objective-C中使用要声明值的声明。在调试版本中,我声明为停止程序执行并检查我的假设是否不正确。但是,在生产版本中,我找到了一种安全失效的方法,可以将对用户的影响降至最低。我通过创建一个将NSAssert封装在if语句中的宏来实现此目的,该语句还执行我想在生产环境中作为故障保护运行的代码。例如:

我将使用的断言宏:

#define AssertTrueOrExecute(condition, action) \
  if (!condition) { \
    NSAssert(testCondition, @"Condition failed"); \
    action; \
  }

在我的应用程序中的某个地方,我会遇到这样的事情:

- (void)someMethod
{
  BOOL testCondition = ...
  // Ensure the testCondition is true before proceeding any further
  AssertTrueOrExecute(testCondition, return);
  // Potentially unsafe code that never gets executed if testCondition is false
}

- (void)someReturningMethod
{
  BOOL testCondition = ...
  // Ensure the testCondition is true before proceeding any further
  AssertTrueOrExecute(testCondition, return @"safe string");
  // Potentially unsafe code that never gets executed if testCondition is false
}

由于我无法像Swift中提到的那样定义宏,是否有一种方法可以实现相同的行为?那就是我要如何为我的AssertTrueOrExecute使用Swift等效项

更新:

为了进一步解释这个问题,如果我使用的是Swift,我目前将编写如下内容:

func someMethod () {
    let testCondition : Bool = ...

    // Ensure the testCondition is true before proceeding any further
    if (!testCondition) {
      assert(testCondition);
      return;
    }
    // Potentially unsafe code that never gets executed if testCondition is false
}

因此,问题更多地在于如何用类似的方式包装带有断言的if语句,使我拥有Objective-C宏,以便例如可以断言或早返回?

更新2:

另一个示例将在函数中返回一些内容,例如:

func someReturningMethod () -> String {
    let testCondition : Bool = ...

    // Ensure the testCondition is true before proceeding any further
    if (!testCondition) {
      assert(testCondition);
      return "safe string";
    }    
    // Potentially unsafe code that never gets executed if testCondition is false
    return "some other string"
}
CouchDeveloper

Swift中没有宏,但是Swift中可能还有其他手段可以实现与Objective-C相同的功能。

但是,这里真正的问题是,您尝试以一种您实际上不应该采用的方式来解决问题:

不要混用程序员错误运行时错误

相反,要清楚地区分什么是程序员错误以及什么是运行时错误使用断言处理程序员错误,并NSError在Swift中分别使用trycatch和来处理运行时错误throw

请注意,程序员错误的“范围”不限于程序由于断言失败而失败的时间:这种错误很可能会带来不良的副作用,使程序处于无效状态,并且此断言通常会检测到错误。断言可能在很长时间之前就发生了。因此,当断言失败时,您的程序很可能已经处于无效状态。

一条经验法则是,断言失败不应在生产代码中发生(请务必阅读)。好吧,这些是程序员的错误,应该解决,不是吗?您可以在单元测试中使用断言来验证您的假设。如果您仍然担心,您的假设可能会中断生产,并且还确保这不是运行时错误(应始终妥善处理),则应停止程序-无论如何,所有赌注都无效。在Swift中,您可以使用fatalError它。

有时,对特定假设的违反是程序员错误还是运行时错误的区分并不总是那么明显,并且可能取决于上下文。但是,作为程序员,您始终可以定义它是什么。以一个字符串参数为例:如果您是直接从想要创建帐户并要求输入用户名的用户输入的文本字段中获取的,则应该验证该字符串并在不适合的情况下返回/抛出错误您的期望-例如,如果它为空,太短等。也就是说,在Swift中,您可能会throw出错并在调用站点(可能是在View Controller中)优雅地处理该错误。另一方面,您定义初始化一个User对象,对象的name将为空。也就是说,在初始化例程中,您定义了一个前提条件,即有效的用户名一定不能为空,然后使用assert或进行检查fatalError在这种情况下,如果没有用于初始化名称为空的用户的代码路径,则您的程序是正确的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

FStar中的未知断言失败

UITextView _firstBaselineOffsetFromTop中的断言失败

dequeueReusableCellWithIdentifier:forIndexPath中的断言失败:

Swift-在Xcode中内联显示断言失败,例如XCTest失败?

UITableView configureCellForDisplay:forIndexPath中的断言失败:

UITableViewController中的断言失败

-[UICollectionView _updateWithItems:tentativelyForReordering:]中的UICollectionView断言失败

UICollectionView中的断言失败?

-[NSLayoutConstraint常量]中的断言失败

断言断言失败

捕获UICollectionView在Swift中执行批处理更新断言失败?

Swift 4--[UICollectionView _createPreparedCellForItemAtIndexPath中的断言失败

断言blobFromImages中的image.depth()失败

fwrite.cpp中的调试断言失败

函数'contourArea'中的OpenCV(4.0.0)断言失败

GMUNonHierarchicalDistanceBasedAlgorithm clustersAtZoom中的断言失败

***-[UIView _addConstraint:]中的断言失败,

将断言失败结果存储在变量中

TableView CoreData错误:Swift中的断言失败

-[UICollectionView _endItemAnimations]崩溃中的断言失败

grunt-mocha-$ .get中的断言失败

createPreparedCellForItemAtIndexPath 中的 UICollectionView 断言失败

即使输出相同,断言在 groovy 中也失败

UITableView Swift 中的断言失败

如何断言所有断言在python中失败

在 CppUnit 中测试中止断言失败

Swift 断言失败

jmes路径断言在jmeter中失败

断言错误:断言失败:在 Databricks 中没有 DeleteFromTable 的计划