由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'+[NSKeyedArchiver unarchiveObjectWithFile:]
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSKeyedArchiver unarchiveObjectWithFile:]
我正在关注开发者 apple 的 FoodTracker 演示。我在最后一节:持久化数据。
我是 运行宁 Xcode 8,正在关注 Swift 3.
上的演示构建
如果我下载代码并转换为 Swift 2.3,它不起作用。如果我转换为 Swift 3.0,它也不起作用。我一直在尝试关注 Swift 3.
上的演示
代码需要一些更改才能编译 运行 Swift 3,到目前为止我已经成功了。
但是,我现在在运行时间得到这个:
FoodTracker[1597:720222] *** 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'+[NSKeyedArchiver unarchiveObjectWithFile:]:无法识别的选择器发送到 class 0x1081497a8'
我对这部分所做的更改是:
1) 在 Meal class 上我添加了两个静态常量:
static let DocumentsDirectory =
FileManager().urls(for: .documentDirectory, in:
.userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
2) 同样在用餐时 class 我添加了一个结构和一个方便的初始化:
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.nameKey)
aCoder.encode(photo, forKey: PropertyKey.photoKey)
aCoder.encode(rating, forKey: PropertyKey.ratingKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: PropertyKey.nameKey) as! String
// Because photo is an optional property of Meal, use conditional cast
let photo = aDecoder.decodeObject(forKey: PropertyKey.photoKey) as? UIImage
let rating = aDecoder.decodeInteger(forKey: PropertyKey.ratingKey)
// Must call designated initializer
self.init(name: name, photo: photo, rating: rating)
}
3) 在 MealTableViewController class 我添加了函数 saveMeals 和 loadMeals:
func saveMeals() {
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile: Meal.ArchiveURL.path)
if !isSuccessfulSave {
print("Failed to save meals...")
}
}
func loadMeals() -> [Meal]? {
return NSKeyedArchiver.classForKeyedUnarchiver().unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
代码编译成功,但在 运行 时崩溃。错误堆栈跟踪的第 5 行似乎指向 Meal class 和 loadMeals 方法作为罪魁祸首:
5 FoodTracker 0x0000000107ce9e44 _TFC11FoodTracker23MealTableViewController9loadMealsfT_GSqGSaCS_4Meal__ + 276
6 FoodTracker 0x0000000107ce701a _TFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 266
7 FoodTracker 0x0000000107ce7222 _TToFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 34
不幸的是,我现在不知道更多,无法跟踪 Xcode 和 Swift 为我留下的面包屑。只是想从源头(Apple Developers)学习。
我已经在网上和这个网站上进行了搜索,但还没有完全找到我能够用来解决问题的答案。这是本教程的最后一部分,我真的很想完成它。感谢您提供的任何帮助;我希望在我精通 Swift 后将其付诸实践。谢谢!
使用NSKeyedUnarchiver
:
func loadMeals() -> [Meal]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
我正在关注开发者 apple 的 FoodTracker 演示。我在最后一节:持久化数据。
我是 运行宁 Xcode 8,正在关注 Swift 3.
上的演示构建如果我下载代码并转换为 Swift 2.3,它不起作用。如果我转换为 Swift 3.0,它也不起作用。我一直在尝试关注 Swift 3.
上的演示代码需要一些更改才能编译 运行 Swift 3,到目前为止我已经成功了。
但是,我现在在运行时间得到这个:
FoodTracker[1597:720222] *** 由于未捕获的异常 'NSInvalidArgumentException' 而终止应用程序,原因:'+[NSKeyedArchiver unarchiveObjectWithFile:]:无法识别的选择器发送到 class 0x1081497a8'
我对这部分所做的更改是: 1) 在 Meal class 上我添加了两个静态常量:
static let DocumentsDirectory =
FileManager().urls(for: .documentDirectory, in:
.userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
2) 同样在用餐时 class 我添加了一个结构和一个方便的初始化:
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.nameKey)
aCoder.encode(photo, forKey: PropertyKey.photoKey)
aCoder.encode(rating, forKey: PropertyKey.ratingKey)
}
required convenience init?(coder aDecoder: NSCoder) {
let name = aDecoder.decodeObject(forKey: PropertyKey.nameKey) as! String
// Because photo is an optional property of Meal, use conditional cast
let photo = aDecoder.decodeObject(forKey: PropertyKey.photoKey) as? UIImage
let rating = aDecoder.decodeInteger(forKey: PropertyKey.ratingKey)
// Must call designated initializer
self.init(name: name, photo: photo, rating: rating)
}
3) 在 MealTableViewController class 我添加了函数 saveMeals 和 loadMeals:
func saveMeals() {
let isSuccessfulSave = NSKeyedArchiver.archiveRootObject(meals, toFile: Meal.ArchiveURL.path)
if !isSuccessfulSave {
print("Failed to save meals...")
}
}
func loadMeals() -> [Meal]? {
return NSKeyedArchiver.classForKeyedUnarchiver().unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}
代码编译成功,但在 运行 时崩溃。错误堆栈跟踪的第 5 行似乎指向 Meal class 和 loadMeals 方法作为罪魁祸首:
5 FoodTracker 0x0000000107ce9e44 _TFC11FoodTracker23MealTableViewController9loadMealsfT_GSqGSaCS_4Meal__ + 276
6 FoodTracker 0x0000000107ce701a _TFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 266
7 FoodTracker 0x0000000107ce7222 _TToFC11FoodTracker23MealTableViewController11viewDidLoadfT_T_ + 34
不幸的是,我现在不知道更多,无法跟踪 Xcode 和 Swift 为我留下的面包屑。只是想从源头(Apple Developers)学习。
我已经在网上和这个网站上进行了搜索,但还没有完全找到我能够用来解决问题的答案。这是本教程的最后一部分,我真的很想完成它。感谢您提供的任何帮助;我希望在我精通 Swift 后将其付诸实践。谢谢!
使用NSKeyedUnarchiver
:
func loadMeals() -> [Meal]? {
return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}