Swift “如何捕捉纳奇弗”;NSInvalidUnarchiveOperationException“;斯威夫特?
我正在Swift中使用Swift “如何捕捉纳奇弗”;NSInvalidUnarchiveOperationException“;斯威夫特?,swift,codable,nskeyedunarchiver,Swift,Codable,Nskeyedunarchiver,我正在Swift中使用Codable与NSKeyedArchiver和NSKeyedArchiver对对象进行内编码/解码 当编码的对象与预期的格式匹配时,一切都很顺利。 但是,如果数据无效或格式不匹配,我将在使用XCTest的单元测试中得到以下断言: 失败:捕获到“NSInvalidUnarchiveOperationException”,“无法读取数据,因为它的格式不正确。” 当解码失败时,我正在使用NSKeyedUnarchiver.decodeTopLevelDecodable方法: 如
Codable
与NSKeyedArchiver
和NSKeyedArchiver
对对象进行内编码/解码
当编码的对象与预期的格式匹配时,一切都很顺利。
但是,如果数据无效或格式不匹配,我将在使用XCTest
的单元测试中得到以下断言:
失败:捕获到“NSInvalidUnarchiveOperationException”,“无法读取数据,因为它的格式不正确。”
当解码失败时,我正在使用NSKeyedUnarchiver.decodeTopLevelDecodable
方法:
如果存档不是有效的属性列表,则此方法将抛出DecodingError.dataCorrupted(u:)
错误。如果存档中的某个值解码失败,此方法将抛出相应的错误
捕获此异常时遇到问题,因为try?
、do/catch
和xctasertthrowserror
似乎都不起作用
测试失败时的完整错误消息:
failed: caught "NSInvalidUnarchiveOperationException", "The data couldn’t be read because it isn’t in the correct format."
(
0 CoreFoundation 0x00007fff315f12db __exceptionPreprocess + 171
1 libobjc.A.dylib 0x00007fff587a1c76 objc_exception_throw + 48
2 Foundation 0x00007fff3376b077 -[NSCoder(Exceptions) __failWithExceptionName:errorCode:format:] + 0
3 Foundation 0x00007fff3376b371 -[NSCoder(Exceptions) __failWithExternalError:] + 161
4 libswiftFoundation.dylib 0x0000000109872453 _T0So17NSKeyedUnarchiverC10FoundationE23decodeTopLevelDecodablexSgxm_SS6forKeytKs0G0RzlF + 403
5 MBOUtilityKit 0x0000000104cba964 _T013MBOUtilityKit17KeyedLocalStorageV3getxSS3key_tKs9DecodableRzs9EncodableRzlF + 772
6 MBOUtilityKitTests macOS 0x0000000104c5144c _T024MBOUtilityKitTests_macOS017KeyedLocalStorageC0C17testDecodeFailureyyKF + 556
7 MBOUtilityKitTests macOS 0x0000000104c51835 _T024MBOUtilityKitTests_macOS017KeyedLocalStorageC0C17testDecodeFailureyyKFTo + 69
8 CoreFoundation 0x00007fff31568bec __invoking___ + 140
9 CoreFoundation 0x00007fff31568ac0 -[NSInvocation invoke] + 320
10 XCTest 0x000000010036c90d __24-[XCTestCase invokeTest]_block_invoke_2.187 + 65
11 XCTest 0x00000001003d6207 -[XCTMemoryChecker _assertInvalidObjectsDeallocatedAfterScope:] + 51
12 XCTest 0x00000001003755ef -[XCTestCase assertInvalidObjectsDeallocatedAfterScope:] + 116
13 XCTest 0x000000010036c89c __24-[XCTestCase invokeTest]_block_invoke.181 + 210
14 XCTest 0x00000001003c8772 +[XCTestCase(Failures) performFailableBlock:shouldInterruptTest:] + 36
15 XCTest 0x00000001003c86bc -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 54
16 XCTest 0x000000010036c4db __24-[XCTestCase invokeTest]_block_invoke + 854
17 XCTest 0x00000001003cd659 -[XCUITestContext performInScope:] + 237
18 XCTest 0x000000010036c170 -[XCTestCase invokeTest] + 175
19 XCTest 0x000000010036dea6 __26-[XCTestCase performTest:]_block_invoke_2 + 42
20 XCTest 0x00000001003c8772 +[XCTestCase(Failures) performFailableBlock:shouldInterruptTest:] + 36
21 XCTest 0x00000001003c86bc -[XCTestCase(Failures) _performTurningExceptionsIntoFailuresInterruptAfterHandling:block:] + 54
22 XCTest 0x000000010036dd53 __26-[XCTestCase performTest:]_block_invoke.326 + 90
23 XCTest 0x00000001003d24a1 +[XCTContext runInContextForTestCase:block:] + 225
24 XCTest 0x000000010036d454 -[XCTestCase performTest:] + 673
25 XCTest 0x00000001003b0555 -[XCTest runTest] + 57
26 XCTest 0x0000000100368b30 __27-[XCTestSuite performTest:]_block_invoke + 365
27 XCTest 0x000000010036830c -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
28 XCTest 0x00000001003685cd -[XCTestSuite performTest:] + 296
29 XCTest 0x00000001003b0555 -[XCTest runTest] + 57
30 XCTest 0x0000000100368b30 __27-[XCTestSuite performTest:]_block_invoke + 365
31 XCTest 0x000000010036830c -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
32 XCTest 0x00000001003685cd -[XCTestSuite performTest:] + 296
33 XCTest 0x00000001003b0555 -[XCTest runTest] + 57
34 XCTest 0x0000000100368b30 __27-[XCTestSuite performTest:]_block_invoke + 365
35 XCTest 0x000000010036830c -[XCTestSuite _performProtectedSectionForTest:testSection:] + 55
36 XCTest 0x00000001003685cd -[XCTestSuite performTest:] + 296
37 XCTest 0x00000001003b0555 -[XCTest runTest] + 57
38 XCTest 0x00000001003e6308 __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 40
39 XCTest 0x000000010038aaa4 -[XCTestObservationCenter _observeTestExecutionForBlock:] + 600
40 XCTest 0x00000001003e610e -[XCTTestRunSession runTestsAndReturnError:] + 369
41 XCTest 0x000000010034f865 -[XCTestDriver runTestsAndReturnError:] + 440
42 XCTest 0x00000001003d10f3 _XCTestMain + 1228
43 xctest 0x0000000100002155 main + 557
44 libdyld.dylib 0x00007fff593bb015 start + 1
45 ??? 0x0000000000000005 0x0 + 5
)
该类的objective-C桥没有正确设置以在Swift中抛出错误,因此您必须创建一个抛出或捕获错误的objective-C包装器 以下是我的超级简单的“安全存档”,您可以从中获得灵感: 安全存档。h:
#import <Foundation/Foundation.h>
@interface SafeUnarchiver : NSObject
+(NSObject* _Nullable)unarchive:(NSData* _Nonnull)data;
@end
别忘了向苹果公司提交一份雷达记录单,这样他们最终可以修复这个未被正确捕获的异常
根据您希望从Swift访问的其他Objective-C代码,您必须将标头添加到您的-桥接标头。该类的Objective-C桥接未正确设置,无法在Swift中抛出错误,因此您必须创建一个抛出或捕获错误的Objective-C包装 以下是我的超级简单的“安全存档”,您可以从中获得灵感: 安全存档。h:
#import <Foundation/Foundation.h>
@interface SafeUnarchiver : NSObject
+(NSObject* _Nullable)unarchive:(NSData* _Nonnull)data;
@end
别忘了向苹果公司提交一份雷达记录单,这样他们最终可以修复这个未被正确捕获的异常
根据您希望从Swift访问的其他Objective-C代码,您必须将头添加到您的桥接头.h,因为iOS 9可以使用:
unarchiveTopLevelObjectWithData(:)
,这会引发异常
例如:
try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
自iOS 9以来,您可以使用:
unarchiveTopLevelObjectWithData(:)
,这会引发异常
例如:
try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data)
您需要设置如下未归档故障策略:
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
unarchiver.decodingFailurePolicy = .setErrorAndReturn
这将使NSKEYEDUNACHIVER返回NSError,该错误将正确转换为您能够捕获的swift异常。您需要设置如下未归档故障策略:
let unarchiver = NSKeyedUnarchiver(forReadingWith: data)
unarchiver.decodingFailurePolicy = .setErrorAndReturn
这将使NSKeyedUnachiver返回N错误,该错误将正确转换为您能够捕获的swift异常。异常和错误在swift中是不同的,而
NSInvalidUnarchiveOperationException
是异常而非错误。您无法捕获Swift代码中的异常。你可能需要想办法绕过它。为什么您需要处理您知道无效或格式不匹配的内容?另外,你最好向苹果公司发送一份错误报告。在Swift中,异常和错误是不同的,而NSInvalidUnarchiveOperationException
是一个异常而不是一个错误。您无法捕获Swift代码中的异常。你可能需要想办法绕过它。为什么您需要处理您知道无效或格式不匹配的内容?另外,你最好向苹果发送一份bug报告。