由于未捕获的异常终止应用程序' NSInvalidArgumentException',原因:' + [NSKeyedArchiver unarchiveObjectWithFile:]

时间:2016-10-23 00:03:37

标签: swift unrecognized-selector nskeyedarchiver

我正在开发者apple上关注FoodTracker演示。我在最后一节:坚持数据。

我正在运行Xcode 8,并遵循Swift 3上的演示构建。

如果我下载代码并转换为Swift 2.3,它就无法运行。如果我转换为Swift 3.0,它也无法正常工作。我一直在尝试按照Swift 3上的演示。

代码需要进行一些更改才能在Swift 3上编译和运行,到目前为止我已经成功了。

但是,我现在在运行时得到这个:

FoodTracker [1597:720222] ***由于未捕获的异常终止应用程序&#39; NSInvalidArgumentException&#39;,原因:&#39; + [NSKeyedArchiver unarchiveObjectWithFile:]:无法识别的选择器发送到类0x1081497a8&#39; < / p>

我为此部分所做的更改是: 1)在Meal类中,我添加了两个静态常量:

static let DocumentsDirectory =
   FileManager().urls(for: .documentDirectory, in:
    .userDomainMask).first! 
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")

2)同样在Meal类上我添加了一个struct和一个方便的init:

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类中,我添加了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类和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,我希望能够付出代价。谢谢!

1 个答案:

答案 0 :(得分:1)

使用NSKeyedUnarchiver

func loadMeals() -> [Meal]? {
    return NSKeyedUnarchiver.unarchiveObject(withFile: Meal.ArchiveURL.path) as? [Meal]
}