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

Posted

技术标签:

【中文标题】由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“+[NSKeyedArchiver unarchiveObjectWithFile:]【英文标题】:Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '+[NSKeyedArchiver unarchiveObjectWithFile:] 【发布时间】:2016-10-23 00:03:37 【问题描述】:

我正在关注开发者 Apple 的 FoodTracker 演示。我在最后一节:持久化数据。

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

如果我下载代码并转换为 Swift 2.3,它就不起作用。如果我转换为 Swift 3.0,它也不起作用。我一直在尝试关注 Swift 3 上的演示。

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

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

FoodTracker[1597:720222] *** :无法识别的选择器发送到类 0x1081497a8”

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

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

2) 我还在 Meal 类上添加了一个结构体和一个方便的 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】:

使用NSKeyedUnarchiver:

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

【讨论】:

谢谢!那正是它的本来面目。现在我查看了教程的代码,我发现 NSKeyeedUnarchiver 实际上是指定的......我一定选择了错误的自动完成选项,然后无法发现关键字的差异。我必须更加注意我不敢承认的代码细节。

以上是关于由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“+[NSKeyedArchiver unarchiveObjectWithFile:]的主要内容,如果未能解决你的问题,请参考以下文章

由于未捕获的异常而终止应用程序 [UIImageView _isResizable]

由于未捕获的异常而终止应用程序,同时加载视图

由于未捕获的异常“NSInternalInconsistencyException”错误而终止应用程序

“由于未捕获的异常而终止应用程序”在推送视图控制器时崩溃

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,

由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序