NSKeyedArchiver和NSKeyedUnarchiver / Swift 3.0

我正在使用NSKeyedArchiverNSKeyedUnarchiverCore-Data存储一些复杂的数据,稍后在我的应用程序中检索它。 直到现在,这个工作完美无缺,但在迁移之后, Swift 3.0似乎并不满意我的代码。

我早在我的代码中:

  var firstArray = [Int](), secondArray = [CGFloat]() ....... // stores some values in firstArray and also in secondArray. ....... 

这里是如何存储数据的代码如下所示:

  let masterArray = [firstArray, secondArray] as [Any] let dataForApp:NSData = NSKeyedArchiver.archivedData(withRootObject: masterArray) as NSData entityFieldsDico = ["dataForAppArray":dataForApp] // Use entityFieldsDico to save dataForApp in Core-Data under the key "dataForAppArray". 

下面是如何检索数据的代码如下所示:

  if let archiveData = dbRecord.value(forKey: "dataForAppArray") { let archiveArray = NSKeyedUnarchiver.unarchiveObject(with: archiveData as! Data) firstArray = (archiveArray as! Array)[0] as [Int] secondArray = (archiveArray as! Array)[1] as [CGFloat] } 

这个问题出现在代码检索数据。 它只是在build立时崩溃。

如果我注释掉这两行:

  //firstArray = (archiveArray as! Array)[0] as [Int] //secondArray = (archiveArray as! Array)[1] as [CGFloat] 

该程序的工作原理,除了firstArray&(显然)不可用的数据。

如果我不把它们评论出来,那么我就会崩溃,一个非常长的信息就像下面的东西一样。 (我添加一些…(点)来缩短信息。)

 ............. 0 swift 0x000000010d71fa3d PrintStackTraceSignalHandler(void*) + 45 1 swift 0x000000010d71f466 SignalHandler(int) + 470 2 libsystem_platform.dylib 0x00007fffa0c5a52a _sigtramp + 26 3 libsystem_platform.dylib 0x0000000000000003 _sigtramp + 1597659891 4 swift 0x000000010b25b4e3 swift::constraints::ConstraintGraphScope::~ConstraintGraphScope() + 899 5 swift 0x000000010b2f45f4 swift::constraints::ConstraintSystem::solveSimplified(llvm::SmallVectorImpl<swift::constraints::Solution>&, swift::FreeTypeVariableBinding) + 24868 ........... Objects-normal/arm64/UP_ViewController.dia -emit-dependencies-path /Users/me/Library/Developer/Xcode/DerivedData/TheApp-dszaazmmftlmwbicuwcwaplkjdfs/Build/Intermediates/TheApp.build/Debug-iphoneos/TheApp.build/Objects-normal/arm64/UP_ViewController.d -emit-reference-dependencies-path /Users/me/Library/Developer/Xcode/DerivedData/TheApp-dszaazmmftlmwbicuwcwaplkjdfs/Build/Intermediates/TheApp.build/Debug-iphoneos/TheApp.build/Objects-normal/arm64/UP_ViewController.swiftdeps -o /Users/me/Library/Developer/Xcode/DerivedData/TheApp-dszaazmmftlmwbicuwcwaplkjdfs/Build/Intermediates/TheApp.build/Debug-iphoneos/TheApp.build/Objects-normal/arm64/UP_ViewController.o -embed-bitcode-marker 1. While type-checking 'computeFunction' at /Users/me/Documents/iOS/TheApp/TheApp/UP_ViewController.swift:184:5 2. While type-checking expression at [/Users/me/Documents/iOS/TheApp/TheApp/UP_ViewController.swift:235:17 - line:235:66] RangeText="firstArray = (archiveArray as! Array)[0] as [Int]" 

我有人遇到过这样的问题,请让我知道你是如何解决这个问题的。

你需要将你的archiveArrayArray<Array<Any>>那么你可以得到包含Anytypes值的数组数组。

对于你的解决scheme是

 if let archiveData = dbRecord.value(forKey: "dataForAppArray") { if let archiveArray = NSKeyedUnarchiver.unarchiveObject(with: archiveData as! Data) as? Array<Array<Any>> { firstArray = archiveArray[0] as! [Int] secondArray = archiveArray[1] as! [CGFloat] } } 

我们举一个例子来理解连击

 var firstArray = [Int](), secondArray = [CGFloat]() firstArray.append(1) firstArray.append(1) firstArray.append(1) secondArray.append(1.1) secondArray.append(1.2) secondArray.append(1.3) print(firstArray) //[1, 1, 1] print(secondArray) //[1.1, 1.2, 1.3] let masterArray = [firstArray, secondArray] as [Any] //[[1, 1, 1], [1.1, 1.2, 1.3]] let dataForApp:NSData = NSKeyedArchiver.archivedData(withRootObject: masterArray) as NSData 

现在unarchiveObject返回Any然后打印输出,所以可以区分两个输出。

 let archiveArray1 = NSKeyedUnarchiver.unarchiveObject(with: dataForApp as Data) print(archiveArray1!) 

输出将是

 ( ( 1, 1, 1 ), ( "1.1", "1.2", "1.3" ) ) 

现在将数组强制转换为Array<Array<Any>>

 if let archiveArray = NSKeyedUnarchiver.unarchiveObject(with: dataForApp as Data) as? Array<Array<Any>> { print(archiveArray) } 

输出将是

 [[1, 1, 1], [1.1, 1.2, 1.3]] 

希望你明白我的观点。