2

ユーザー作成の式(「2 + 2」、「5 + 7」以上の複合語など)を検証する必要があります。 NSExpressionクラスを使用して、この式を解析して計算します。これは私の遊び場コードです:NSExpressionを使用しているときにNSInvalidArgumentExceptionをキャッチする正しい方法

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のクラスを使用し、そのクラスで私は本当にこのような例外をキャッチすることができます

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

これは動作し、私は正しいパース状態(ゼロ手段を得ることができます表現の問題)と結果(NSNumber)がありますが、私は本当にスウィフトでこのすべてのことを正確かつ完全に行う方法を理解したいと思います。

答えて

2

NSInvalidArgumentExceptionは、Java例外の意味で捕捉可能なエラーではありません。アップルは、この例外を犯したときにあなたのプログラムが正しい状態にあることを保証しておらず、何かが間違ってしまう可能性があります。

文字列がメソッドに渡される前に、文字列が有効かどうかを確認するために、他のメカニズムを使用することをお勧めします。

+0

ありがとうございます。 "expression solving"だけでなく、 "expression validation"をサポートするライブラリを使うほうがよいようです。今私はhttps://github.com/davedelong/DDMathParserを見ています –

2

これは本はココアとObjective-Chas to sayでスウィフトを使用するものである:

スウィフトエラーハンドリングはObjective-Cの中の例外処理に似ていますが、それは全く別の機能です。 Objective-Cメソッドが実行時に例外をスローした場合、Swiftは実行時エラーをトリガします。 Objective-Cの例外をSwiftで直接リカバリする方法はありません。例外処理の動作は、Swiftが使用するObjective-Cコードで実装する必要があります。

[マイ太字]はちょうど私は問題の周りの簡単な方法を見ることはできません 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にインポートされます。

Objective-Cの例外は、プログラムを一貫した状態にすることは実際には保証されていないと言います。この場合、指が交差しても問題ありません。

関連する問題