我正在尝试这个计算器代码。如何处理用户无效的输入?
//答案:将标题桥接到Objective-C // https://github.com/kongtomorrow/TryCatchFinally-Swift
这是同样的问题但是在objc但是我想在swift中这样做。 Catching NSInvalidArgumentException from NSExpression
我想要展示的是一条消息,如果它不起作用,但现在当用户没有输入正确的格式时我会收到异常。
import Foundation
var equation:NSString = "60****2" // This gives a NSInvalidArgumentException',
let expr = NSExpression(format: equation) // reason: 'Unable to parse the format string
if let result = expr.expressionValueWithObject(nil, context: nil) as? NSNumber {
let x = result.doubleValue
println(x)
} else {
println("failed")
}
答案 0 :(得分:10)
更多" Swifty"溶液:
@implementation TryCatch
+ (BOOL)tryBlock:(void(^)())tryBlock
error:(NSError **)error
{
@try {
tryBlock ? tryBlock() : nil;
}
@catch (NSException *exception) {
if (error) {
*error = [NSError errorWithDomain:@"com.something"
code:42
userInfo:@{NSLocalizedDescriptionKey: exception.name}];
}
return NO;
}
return YES;
}
@end
这将生成Swift代码:
class func tryBlock((() -> Void)!) throws
您可以将其与try
:
do {
try TryCatch.tryBlock {
let expr = NSExpression(format: "60****2")
...
}
} catch {
// Handle error here
}
答案 1 :(得分:7)
这仍然是Swift 2中的一个问题。如上所述,最好的解决方案是使用桥接头并捕获Objective C中的NSException。
https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8描述了一个很好的解决方案,但确切的代码并没有在Swift 2中编译,因为try
和catch
现在是保留关键字。您需要更改方法签名以解决此问题。这是一个例子:
// https://medium.com/swift-programming/adding-try-catch-to-swift-71ab27bcb5b8
@interface TryCatch : NSObject
+ (void)tryBlock:(void (^)())try catchBlock:(void (^)(NSException *))catch finallyBlock:(void (^)())finally;
@end
@implementation TryCatch
+ (void)tryBlock:(void (^)())try catchBlock:(void (^)(NSException *))catch finallyBlock:(void (^)())finally {
@try {
try ? try() : nil;
}
@catch (NSException *e) {
catch ? catch(e) : nil;
}
@finally {
finally ? finally() : nil;
}
}
@end
答案 2 :(得分:1)
从https://github.com/kongtomorrow/TryCatchFinally-Swift编辑一个不错的解决方案:
首先创建TryCatch.h
& TryCatch.m
并将它们连接到Swift:
<强> TryCatch.h 强>
#import <Foundation/Foundation.h>
void tryCatch(void(^tryBlock)(), void(^catchBlock)(NSException *e), void(^finallyBlock)());
<强> TryCatch.m 强>
#import <Foundation/Foundation.h>
void tryCatch(void(^tryBlock)(), void(^catchBlock)(NSException *e), void(^finallyBlock)()) {
@try {
tryBlock();
}
@catch (NSException *exception) {
catchBlock(exception);
}
@finally {
finallyBlock();
}
}
然后在Swift中创建类TryCatch
:
func `try`(`try`:()->()) -> TryCatch {
return TryCatch(`try`)
}
class TryCatch {
let tryFunc : ()->()
var catchFunc = { (e:NSException!)->() in return }
var finallyFunc : ()->() = {}
init(_ `try`:()->()) {
tryFunc = `try`
}
func `catch`(`catch`:(NSException)->()) -> TryCatch {
// objc bridging needs NSException!, not NSException as we'd like to expose to clients.
catchFunc = { (e:NSException!) in `catch`(e) }
return self
}
func finally(finally:()->()) {
finallyFunc = finally
}
deinit {
tryCatch(tryFunc, catchFunc, finallyFunc)
}
}
最后,使用它! :)
`try` {
let expn = NSExpression(format: "60****2")
//let resultFloat = expn.expressionValueWithObject(nil, context: nil).floatValue
// Other things...
}.`catch` { e in
// Handle error here...
print("Error: \(e)")
}