Swift 3改变了NSCoder的工作方式.
正如其他SO问题所提到的,要解码像Int或类似的值类型Bool,您必须使用特定的函数.例如,decodeInteger用于解码Int像这样的值:
let value = decodeInteger(forKey key: TestKey)
Run Code Online (Sandbox Code Playgroud)
但是如果返回的值decodeInteger是a String或者Bool除了a 之外的东西Int呢?
或者,如果TestKey实际上映射到什么都没有,因为它包含错误的密钥数据?
你如何优雅地捕捉到这些错误?
使用decodeInteger一个非整数的关键将引发异常.可悲的是,它是NSExceptionSwift无法直接处理的(参见下面的参考资料).
您需要首先编写一个包装器来处理ObjC中的ObjC异常并将其桥接到Swift(受此答案的启发):
/// -------------------------------------------
/// 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
Run Code Online (Sandbox Code Playgroud)
现在你可以在Swift中捕获异常了:
do {
try ObjC.catchException {
let age = aDecoder.decodeInteger(forKey: "firstName")
}
} catch {
print(error.localizedDescription)
}
Run Code Online (Sandbox Code Playgroud)
参考:使用ObjectiveC和Swift:采用Cocoa设计模式
虽然Swift错误处理类似于Objective-C中的异常处理,但它是完全独立的功能.如果Objective-C方法在运行时抛出异常,则Swift会触发运行时错误.无法直接在Swift中从Objective-C异常中恢复.必须在Swift使用的Objective-C代码中实现任何异常处理行为.
| 归档时间: |
|
| 查看次数: |
2185 次 |
| 最近记录: |