我正试图摆脱归档对象。我正在关注Apple的示例项目持久性:https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/PersistData.html
基本上有一个符合NSCoding协议的Meal类。但是,当我运行测试来存档/取消归档此Meal对象时,我收到以下错误:
Could not cast value of type 'MyProj.Meal' (0x105373f68) to 'MyProj.Meal' (0x11f5ee928)
这是产生错误的代码;错误发生在第三行:
let meal = Meal(name: "food", photo: nil, rating: 4)!
let data = NSKeyedArchiver.archivedData(withRootObject: meal)
let unarchivedMeal = NSKeyedUnarchiver.unarchiveObject(with: data) as! Meal
XCTAssertNotNil(unarchivedMeal)
以下是Apple的餐饮课程:
//
// Meal.swift
// FoodTracker
//
// Created by Jane Appleseed on 11/10/16.
// Copyright © 2016 Apple Inc. All rights reserved.
//
import UIKit
import os.log
class Meal: NSObject, NSCoding {
//MARK: Properties
var name: String
var photo: UIImage?
var rating: Int
//MARK: Archiving Paths
static let DocumentsDirectory = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first!
static let ArchiveURL = DocumentsDirectory.appendingPathComponent("meals")
//MARK: Types
struct PropertyKey {
static let name = "name"
static let photo = "photo"
static let rating = "rating"
}
//MARK: Initialization
init?(name: String, photo: UIImage?, rating: Int) {
// The name must not be empty
guard !name.isEmpty else {
return nil
}
// The rating must be between 0 and 5 inclusively
guard (rating >= 0) && (rating <= 5) else {
return nil
}
// Initialization should fail if there is no name or if the rating is negative.
if name.isEmpty || rating < 0 {
return nil
}
// Initialize stored properties.
self.name = name
self.photo = photo
self.rating = rating
}
//MARK: NSCoding
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: PropertyKey.name)
aCoder.encode(photo, forKey: PropertyKey.photo)
aCoder.encode(rating, forKey: PropertyKey.rating)
}
required convenience init?(coder aDecoder: NSCoder) {
// The name is required. If we cannot decode a name string, the initializer should fail.
guard let name = aDecoder.decodeObject(forKey: PropertyKey.name) as? String else {
debugPrint("Unable to decode the name for a Meal object.")
return nil
}
// Because photo is an optional property of Meal, just use conditional cast.
let photo = aDecoder.decodeObject(forKey: PropertyKey.photo) as? UIImage
let rating = aDecoder.decodeInteger(forKey: PropertyKey.rating)
// Must call designated initializer.
self.init(name: name, photo: photo, rating: rating)
}
}
有什么想法吗?这真是令人沮丧