代码之家  ›  专栏  ›  技术社区  ›  H4Hugo

Swift-核心数据和NSCoding:未能调用指定的初始值设定项

  •  0
  • H4Hugo  · 技术社区  · 9 年前

    我在Swift中遇到了以下情况:

    我有一个名为Event的NSManaged类:

    import UIKit
    import Foundation
    import CoreData
    
    class Event: NSManagedObject, NSCoding {
    
    @NSManaged var eventArchived: Bool
    @NSManaged var eventCCRecipientAddress: String?
    @NSManaged var eventCCRecipientName: String?
    @NSManaged var eventEndDate: String?
    @NSManaged var eventEndRSVPDateTime: String?
    @NSManaged var eventHappeningId: String?
    @NSManaged var eventName: String?
    @NSManaged var eventResourcesFolderName: String?
    @NSManaged var eventStartDate: String?
    @NSManaged var eventId: String?
    @NSManaged var eventHappening: Happening
    
    override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
        super.init(entity: entity, insertIntoManagedObjectContext: context)
    }
    
    // MARK: NSCoding protocol conformance
    required init(coder aDecoder: NSCoder) {
    
        let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
        let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: context)!
    
        // Note: pass `nil` to `insertIntoManagedObjectContext`
        super.init(entity: entity, insertIntoManagedObjectContext: nil)
    
        if let eventArchived = aDecoder.decodeObjectForKey("eventArchived") as? Bool {
            self.eventArchived = eventArchived
        }
        if let eventCCRecipientAddress = aDecoder.decodeObjectForKey("eventCCRecipientAddress") as? String {
            self.eventCCRecipientAddress = eventCCRecipientAddress
        }
        if let eventCCRecipientName = aDecoder.decodeObjectForKey("eventCCRecipientName") as? String {
            self.eventCCRecipientName = eventCCRecipientName
        }
        if let eventEndDate = aDecoder.decodeObjectForKey("eventEndDate") as? String {
            self.eventEndDate = eventEndDate
        }
        if let eventEndRSVPDateTime = aDecoder.decodeObjectForKey("eventEndRSVPDateTime") as? String {
            self.eventEndRSVPDateTime = eventEndRSVPDateTime
        }
        if let eventHappeningId = aDecoder.decodeObjectForKey("eventHappeningId") as? String {
            self.eventHappeningId = eventHappeningId
        }
        if let eventName = aDecoder.decodeObjectForKey("eventName") as? String {
            self.eventName = eventName
        }
        if let eventResourcesFolderName = aDecoder.decodeObjectForKey("eventResourcesFolderName") as? String {
            self.eventResourcesFolderName = eventResourcesFolderName
        }
        if let eventStartDate = aDecoder.decodeObjectForKey("eventStartDate") as? String {
            self.eventStartDate = eventStartDate
        }
        if let eventId = aDecoder.decodeObjectForKey("eventId") as? String {
            self.eventId = eventId
        }
    }
    
    func encodeWithCoder(aCoder: NSCoder) {
    
        aCoder.encodeObject(eventArchived, forKey: "eventArchived")
    
        if let eventCCRecipientAddress = self.eventCCRecipientAddress {
            aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
        }
        if let eventCCRecipientName = self.eventCCRecipientName {
            aCoder.encodeObject(eventCCRecipientName, forKey: "eventCCRecipientName")
        }
        if let eventEndDate = self.eventEndDate {
            aCoder.encodeObject(eventEndDate, forKey: "eventEndDate")
        }
        if let eventEndRSVPDateTime = self.eventEndRSVPDateTime {
            aCoder.encodeObject(eventEndRSVPDateTime, forKey: "eventEndRSVPDateTime")
        }
        if let eventCCRecipientAddress = self.eventCCRecipientAddress {
            aCoder.encodeObject(eventCCRecipientAddress, forKey: "eventCCRecipientAddress")
        }
        if let eventHappeningId = self.eventHappeningId {
            aCoder.encodeObject(eventHappeningId, forKey: "eventHappeningId")
        }
        if let eventName = self.eventName {
            aCoder.encodeObject(eventName, forKey: "eventName")
        }
        if let eventResourcesFolderName = self.eventResourcesFolderName {
            aCoder.encodeObject(eventResourcesFolderName, forKey: "eventResourcesFolderName")
        }
        if let eventStartDate = self.eventStartDate {
            aCoder.encodeObject(eventStartDate, forKey: "eventStartDate")
        }
        if let eventId = self.eventId {
            aCoder.encodeObject(eventId, forKey: "eventId")
        }
    
        aCoder.encodeObject(eventHappening, forKey: "eventHappening")
    }
    }
    

    在我被要求实现NSCoding协议之前,这个类只使用NSManaged变量。我使用NSCoding是因为我需要知道我的应用程序中任何地方的当前事件,包括离线模式。

    当我尝试使用事件类时,始终出现以下错误:

    CoreData: error: Failed to call designated initializer on NSManagedObject class 'AccueilInviteVIP.Event' 
    

    这是我尝试访问班级的方式:

    var currentEvent = Event()
    

    然后在viewDidLoad方法中:

        // currentEvent
        currentEvent = NSEntityDescription.insertNewObjectForEntityForName("Event", inManagedObjectContext: self.managedObjectContext!) as! Event
    

    它在这条线上崩溃了。

    错误应该很明显,我的init方法似乎不正确,但我无法让它正常工作,因为我是Swift新手,找不到任何类似的例子。

    任何帮助都会很棒!

    非常感谢。

    雨果

    1 回复  |  直到 9 年前
        1
  •  0
  •   Mundi    9 年前

    看起来像是过度工程,代码太多了。

    为什么不存储eventId并从核心数据中检索对象?此外,归档它看起来非常杂乱和多余。

    // store
    NSUserDefaults.standardUserDefaults().setObject(event.eventId forKey:"mainEventID")
    
    // retrieve
    let eventId = NSUserDefaults.standardUserDefaults().stringForKey("mainEventId")!
    let request = NSFetchRequest(entityName: "Event")
    request.predicate = NSPredicate(format: "eventId = %@", eventId)
    let event = (context.executeFetchRequest(request, error:nil) as [Event]).first!
    

    你必须再犯一些错误 nil 检查,但你明白了。