使用NSExpression时正确的方式来捕获NSInvalidArgumentException [英] Correct way to catch NSInvalidArgumentException when using NSExpression

查看:271
本文介绍了使用NSExpression时正确的方式来捕获NSInvalidArgumentException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想验证用户创建的表达式(如2 + 2,5 + 7或更复杂)。我使用NSExpression类来解析和计算这个表达式。这是我的Playground代码:

I want to validate user created expressions (like "2+2", "5+7" or more complex). I use NSExpression class to parse and calculate this expressions. This is my Playground code:

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+)。有了这个字符串,我的应用程序会崩溃:

When I use valid expression ("2+2") - I get the result. But sometime user can provide wrong string ("2+" for example). With this string my app crashes with this:

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

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

I don't understand how I can catch this exception and why code above don't do this. Now I use Objective C class (with same logic), calling this method from my swift code, and in that class I really can catch such exception:

+(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中正确和完整地完成所有这些事情。

This works and I can get correct parse state (nil means problems with expression) and result (NSNumber), but I really want to understand how to do all this things correct and entirely in Swift.

推荐答案

是什么书籍使用Swift与Cocoa和Objective-C 不得不说

This is what the book Using Swift with Cocoa and Objective-C has to say:


尽管Swift错误处理类似于Objective-C中的异常处理,但它是完全独立的功能。如果Objective-C方法在运行时抛出异常,Swift会触发运行时错误。 无法从Swift中直接从Objective-C异常中恢复。任何异常处理行为必须在Swift使用的Objective-C代码中实现。

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函数:

Having just skimmed the reference for NSExpression I can't see a simple way around the issue. The quote above recommends writing a a bit of Objective-C code to do it. The simplest way is probably to create a C function:

声明:

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。

The function returns nil for expressions that are in error.

您可能会添加一个 NSError ** 参数,以便在发生故障时使用。您也可以在 NSExpression 中的类别中使用此方法,然后返回无效的错误/填充NSError模式可能会导入Swift作为Swift投掷方法。

You could probably add an NSError** parameter to be used when there is a failure. You could also probably make this a method in a category on NSExpression and then the return nil for error/fill in NSError pattern would probably be imported to Swift as a Swift throwing method.

顺便说一下,Objective-C异常并没有真正保证让程序保持一致状态。在这种情况下,手指越过它就可以。

I should say, by the way, that an Objective-C exception is not really guaranteed to leave your program in a consistent state. Fingers crossed it is OK in this case.

这篇关于使用NSExpression时正确的方式来捕获NSInvalidArgumentException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆