2016-11-29 137 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