7

我有以下代码,用于获取已归档对象的路径

let paths = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
let path = paths[0] as String
let archivePath = path.stringByAppendingString("archivePath")

当我运行此代码时,它在NSSearchPathForDirectoriesInDomains调用时崩溃并显示 lldb

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

在 Xcode 的变量视图中,我看到了我所期望的路径字符串集。在 Swift 中获取用于归档/取消归档对象的用户目录的正确方法是什么?

更新

看来这实际上在我使用 NSKeyedUnarchiver 时崩溃了:

stopwatches = NSKeyedUnarchiver.unarchiveObjectWithFile(archivePath) as Stopwatch []

秒表是一个实现 NSCoding 的类,秒表是执行取消归档的视图所拥有的数据源(一个秒表数组)。

更新 2

归档的对象图是一个秒表数组。NSCoding 实现如下:

func encodeWithCoder(aCoder: NSCoder!) {
    aCoder.encodeBool(self.started, forKey: "started")
    aCoder.encodeBool(self.paused, forKey: "paused")
    aCoder.encodeObject(self.startTime, forKey: "startTime")
    aCoder.encodeObject(self.pauseTime, forKey: "pauseTime")
    aCoder.encodeInteger(self.id, forKey: "id")
}

init(coder aDecoder: NSCoder!) {
    self.started = aDecoder.decodeBoolForKey("started")
    self.paused = aDecoder.decodeBoolForKey("paused")
    self.startTime = aDecoder.decodeObjectForKey("startTime") as NSDate
    self.pauseTime = aDecoder.decodeObjectForKey("pauseTime") as NSDate
    self.id = aDecoder.decodeIntegerForKey("id")
    super.init()
}

更新 3expandTilde设置为 true 我的路径是/Users/Justin/Library/Developer/CoreSimulator/Devices/FF808CCD-709F-408D-9416-E‌​E47B306309D/data/Containers/Data/Application/B39CCB84-F335-4B70-B732-5C3C26B4F6AC‌​/Documents/ArchivePath

如果我设置expandTilde为false,我不会崩溃,但是文件没有归档和取消归档,路径是@"~/Documents/ArchivePath"

删除应用程序文件夹会导致应用程序的首次启动不会崩溃,但不允许之后重新打开。此外,在删除应用程序文件夹后,我现在可以读取 lldb 中的存档路径,而不必打印它。

4

1 回答 1

8

我遇到了类似的问题,它与 Swift 的名称修改有关。如果您正在从编码的 Objective-C 对象生成的文件中读取,并且每个对象都有 Objective-C 类名Stopwatch,那么您将无法直接将其解码为 Swift 对象,因为 Swift 对类和符号名称。您Stopwatch在 Swift 代码中看到的内容在内部类似于T23323234_Stopwatch_3242.

要绕过它,请指定应使用特定的 Objective-C 类名导出您的 Swift 类,例如:

@objc(Stopwatch) class Stopwatch {
  ...
}

whereStopwatch匹配你归档的 Objective-C 对象的类名。

编辑:在您在评论中链接的项目代码中,这里还有第二个问题,即尝试编码/解码 Swift 特定的功能。只有 Objective-C 对象可以归档和取消归档。遗憾的是,结构、泛型、元组和可选项与 Objective-C 不兼容,并且不能与NSCoding. 解决此问题的最佳方法是将 Swift 类型编码为NSDictionary实例,例如(未经测试):

let encodedLaps = self.laps.map { lap => ["start": lap.start, "end": lap.end] }
aCoder.encodeObject(encodedLaps, forKey: "laps")

编辑 2:与我上面写的相反,这不仅限于从 Swift 中读取 Objective-C 实例。似乎任何使用都NSCoding需要为您的类提供一个 Objective-C 名称。我想这是因为 Swift 名称修饰可以在编译器的不同运行之间发生变化。

于 2014-07-13T02:56:11.197 回答