2016-11-29 78 views
1

我的应用程序委托因NSException崩溃而崩溃。我使用了异常断点工具来查找它崩溃的地方(在NSUnarchiver期间在init()内部)以及名为ItemStore的文件中添加了一个注释。请帮我解决这个错误,我已经尝试了所有的想法。NSKeyedUnArchiver崩溃

没有异常断点,这是大跌

2016-11-29 09:46:42.546 Foodie[3100:386241] *** Terminating app due to uncaught exception 'NSInvalidUnarchiveOperationException', reason: '*** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode object of class (Photomania.Item) for key (NS.objects); the class may be defined in source code or a library that is not linked' 

当我使用异常断点处,我收到标有星号线异常低于ItemStore。

ItemStore.swift:

import Foundation 

class ItemStore { 

var allItems: [Item] = [] 
let itemArchiveURL: NSURL = { 
    let documentsDirectories = 
    NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, 
     inDomains: .UserDomainMask) 
    let documentDirectory = documentsDirectories.first! 
    return documentDirectory.URLByAppendingPathComponent("items.archive") 
    }() 

init() { 

    // here is the crash 
    if let archivedItems = 
     NSKeyedUnarchiver.unarchiveObjectWithFile(itemArchiveURL.path!) as? [Item] { 
      allItems += archivedItems 
    } 
} 

func moveItemAtIndex(fromIndex: Int, toIndex: Int) { 
    if fromIndex == toIndex { 
     return 
    } 

    // Get reference to object being moved so you can re-insert it 
    let movedItem = allItems[fromIndex] 

    // Remove item from array 
    allItems.removeAtIndex(fromIndex) 

    // Insert item in array at new location 
    allItems.insert(movedItem, atIndex: toIndex) 
} 

func createItem() -> Item { 
    let newItem = Item(random: true) 

    allItems.append(newItem) 

    return newItem 
} 

func removeItem(item: Item) { 
    if let index = allItems.indexOf(item) { 
     allItems.removeAtIndex(index) 
    } 
} 

func saveChanges() -> Bool { 
    print("Saving items to: \(itemArchiveURL.path!)") 
    return NSKeyedArchiver.archiveRootObject(allItems, toFile: itemArchiveURL.path!) 
} 

} 

应用代表:

import UIKit 

@UIApplicationMain 
class AppDelegate: UIResponder, UIApplicationDelegate { 

var window: UIWindow? 

// Override point for customization after application launch. 

//Create an ImageStore 
//let imageStore = ImageStore() 
//let itemStore = ItemStore() 

//Access the ItemsViewController and set its item store 
//let navController = window!.rootViewController as! UINavigationController 
//let itemsController = navController.topViewController as! ItemsViewController 

//itemsController.itemStore = itemStore 
//itemsController.imageStore = imageStore 

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 

    let rootController = window?.rootViewController 

    if rootController is UITabBarController { 
     let firstTabItem = (rootController as! UITabBarController).viewControllers?[0] 

     if firstTabItem is UINavigationController { 

      let firstController = (firstTabItem as! UINavigationController).viewControllers.first as! ItemsViewController 
      firstController.itemStore = ItemStore() 
      firstController.imageStore = ImageStore() 
     } 
    } 
    return true 
} 

... 

} 

Photomania.Item:

import UIKit 

class Item: NSObject, NSCoding { 

var meal: String 
var restaurantName: String? 
var valueInDollars: Int 
let dateCreated: NSDate 
let itemKey: String 

init(meal: String, restaurantName: String?, valueInDollars: Int) { 
    self.meal = meal 
    self.restaurantName = restaurantName 
    self.valueInDollars = valueInDollars 
    self.dateCreated = NSDate() 
    self.itemKey = NSUUID().UUIDString 
} 

convenience init(random: Bool = false) { 
    if random { 
     let nouns = ["Meal"] 
     let places = ["Restaurant"] 

     var idx = arc4random_uniform(UInt32(nouns.count)) 
     let randomNoun = nouns[Int(idx)] 

     idx = arc4random_uniform(UInt32(places.count)) 
     let randomPlace = places[Int(idx)] 

     let randomName = "\(randomNoun)" 
     let randomValue = Int(arc4random_uniform(100)) 
     let randomRestaurantName = "\(randomPlace)" 

     self.init(meal: randomName, 
      restaurantName: randomRestaurantName, 
      valueInDollars: randomValue) 
    } 
    else { 
     self.init(meal: "", restaurantName: nil, valueInDollars: 0) 
    } 
} 

    required init(coder aDecoder: NSCoder) { 
    meal = aDecoder.decodeObjectForKey("meal") as! String 
    dateCreated = aDecoder.decodeObjectForKey("dateCreated") as! NSDate 
    itemKey = aDecoder.decodeObjectForKey("itemKey") as! String 
    restaurantName = aDecoder.decodeObjectForKey("restaurantName") as! String? 

    valueInDollars = aDecoder.decodeIntegerForKey("valueInDollars") 

    super.init() 
} 

    func encodeWithCoder(aCoder: NSCoder) { 
     aCoder.encodeObject(meal, forKey: "meal") 
     aCoder.encodeObject(dateCreated, forKey: "dateCreated") 
     aCoder.encodeObject(itemKey, forKey: "itemKey") 
     aCoder.encodeObject(restaurantName, forKey: "restaurantName") 

     aCoder.encodeInteger(valueInDollars, forKey: "valueInDollars") 
    } 

} 
+0

请张贴崩溃的全部细节。什么是异常被提出?什么是完整的错误和回溯? – JAL

+0

@JAL我编辑了我的问题的细节。 – Allie

+0

什么是Photomania.Item? – JAL

回答

-1

你did'nt显示您Photomania.Item类/结构,但它应该符合NSCoding协议。看看这个例子: http://mhorga.org/2015/08/25/ios-persistence-with-nscoder-and-nskeyedarchiver.html

+0

我不明白这是如何适用于我的班。我试图插入示例材料,但有很多错误。我添加了原始的Photomania.Item类到我的问题的底部。 – Allie

+0

您又添加了ItemStore,我没有看到Item类 –

+0

我修正了它。对不起 – Allie