当前位置 : 主页 > 手机开发 > 其它 >

swift – 使用NSExpression时捕获NSInvalidArgumentException的正确方法

来源:互联网 收集:自由互联 发布时间:2021-06-11
参见英文答案 Catch an exception for invalid user input in swift3个 我想验证用户创建的表达式(如“2 2”,“5 7”或更复杂).我使用NSExpression类来解析和计算这个表达式.这是我的Playground代码: imp
参见英文答案 > Catch an exception for invalid user input in swift                                    3个
我想验证用户创建的表达式(如“2 2”,“5 7”或更复杂).我使用NSExpression类来解析和计算这个表达式.这是我的Playground代码:

import UIKit

let string = "2+2"

var ex:NSExpression?
do {
    ex = NSExpression(format: string)
}
catch {
    print("String is not valid expression")
}

if let result = ex?.expressionValue(with: nil, context: nil) as! NSNumber? {
    print("result is \(result)")
}

当我使用有效表达式(“2 2”)时 – 我得到了结果.但有时用户可以提供错误的字符串(例如“2”).有了这个字符串我的应用程序崩溃与此:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "2+ == 1"'

我不明白我怎么能抓住这个异常以及上面的代码为什么不这样做.现在我使用Objective C类(具有相同的逻辑),从我的swift代码调用此方法,并在该类中我真的可以捕获这样的异常:

+(NSNumber *)solveExpression:(NSString *)string
{
    id value;
    @try {
        NSExpression *ex = [NSExpression expressionWithFormat:string];
        value = [ex expressionValueWithObject:nil context:nil];
    }
    @catch (NSException *e) { }
    return value;
}

这有效,我可以得到正确的解析状态(nil表示表达式问题)和结果(NSNumber),但我真的想要了解如何在Swift中正确完成所有这些事情.

这就是使用Swift与Cocoa和Objective-C has to say的书:

Although Swift error handling resembles exception handling in Objective-C, it is entirely separate functionality. If an Objective-C method throws an exception during runtime, Swift triggers a runtime error. There is no way to recover from Objective-C exceptions directly in Swift. Any exception handling behavior must be implemented in Objective-C code used by Swift.

[我的大胆]

刚刚浏览了NSExpression的参考资料,我无法看到解决问题的简单方法.上面的引用建议编写一些Objective-C代码来完成它.最简单的方法可能是创建一个C函数:

宣言:

extern NSExpression* _Nullable makeExpression(NSString* format _Nonnull);

定义

NSExpression* _Nullable makeExpression(NSString* format _Nonnull)
{
    NSExpression* ret = nil;
    @try 
    {
        // create and assign the expression to ret
    }
    @catch(NSException* e)
    {
        // ignore
    }
    return ret;
}

对于出错的表达式,该函数返回nil.

您可以添加一个NSError **参数,以便在出现故障时使用.您也可以在NSExpression上将其作为类别中的方法,然后NSError模式中的错误/填充的返回nil可能会作为Swift投掷方法导入Swift.

顺便说一句,我应该说,Objective-C异常并不能保证让程序保持一致状态.在这种情况下,手指越过它是可以的.

网友评论