Swift 3改变了NSCoder的工作方式。
正如其他SO问题所提到的,要解码像Int
或Bool
这样的值类型,您必须使用特定的函数。例如,decodeInteger用于解码Int
值,如下所示:
let value = decodeInteger(forKey key: TestKey)
但如果decodeInteger
返回的值是String
或Bool
或Int
以外的其他内容怎么办?
或者,如果TestKey实际上映射到什么都没有,因为它包含错误的密钥数据?
如何优雅地捕捉到这些错误?
答案 0 :(得分:5)
在非整数键上使用decodeInteger
会引发异常。可悲的是,它是一个NSException
,Swift无法直接处理(参见下面的参考资料)。
您需要首先编写一个包装器来处理ObjC中的ObjC异常并将其桥接到Swift(受this answer启发):
/// -------------------------------------------
/// ObjC.h
/// -------------------------------------------
#import <Foundation/Foundation.h>
@interface ObjC : NSObject
+ (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error;
@end
/// -------------------------------------------
/// ObjC.m
/// -------------------------------------------
#import "ObjC.h"
@implementation ObjC
+ (BOOL)catchException:(void(^)())tryBlock error:(__autoreleasing NSError **)error {
@try {
tryBlock();
return YES;
}
@catch (NSException *exception) {
NSMutableDictionary * userInfo = [NSMutableDictionary dictionaryWithDictionary:exception.userInfo];
[userInfo setValue:exception.reason forKey:NSLocalizedDescriptionKey];
[userInfo setValue:exception.name forKey:NSUnderlyingErrorKey];
*error = [[NSError alloc] initWithDomain:exception.name
code:0
userInfo:userInfo];
return NO;
}
}
@end
现在你可以在Swift中捕获异常:
do {
try ObjC.catchException {
let age = aDecoder.decodeInteger(forKey: "firstName")
}
} catch {
print(error.localizedDescription)
}
参考文献:Using ObjectiveC with Swift: Adopting Cocoa Design Patterns
尽管Swift错误处理类似于Objective-C中的异常处理,但它完全是独立的功能。如果Objective-C方法在运行时抛出异常,则Swift会触发运行时错误。无法直接在Swift中从Objective-C异常中恢复。必须在Swift使用的Objective-C代码中实现任何异常处理行为。