带有 NSManagedObject 的 EVReflection 崩溃/不工作

Posted

技术标签:

【中文标题】带有 NSManagedObject 的 EVReflection 崩溃/不工作【英文标题】:EVReflection with NSManagedObject Crashes / not Working 【发布时间】:2017-04-24 15:11:53 【问题描述】:

hI:我一直在使用 EVReflection 使我们的网络层完全安静,我必须说:太棒了!感谢 @evermeer 提供这个库。你可以在这里得到它:https://github.com/evermeer/EVReflection

现在,问题:

下一步是将这些对象直接放入核心数据中。这是问题中的课程之一

// 这是文档中声称的带有 EVReflectable 扩展的对象:

import Foundation
import CoreData
import EVReflection

public class NGTripSummary: NSManagedObject  

extension NGTripSummary: EVReflectable  

// 这里是对象属性:

// NGTripSummary+CoreDataProperties.swift

import Foundation
import CoreData

extension NGTripSummary 

    @nonobjc public class func fetchRequest() -> NSFetchRequest<NGTripSummary> 
        return NSFetchRequest<NGTripSummary>(entityName: "NGTripSummary")
    

    @NSManaged public var carId: Int64
    @NSManaged public var citiesVisited: NSObject?
    @NSManaged public var cost: Double
    @NSManaged public var distance: Double
    @NSManaged public var globalStartDate: NSDate?
    @NSManaged public var globalEndDate: NSDate?
    @NSManaged public var kpl: Double
    @NSManaged public var litres: Double
    @NSManaged public var routeLocations: NSObject?
    @NSManaged public var sessionId: Int64
    @NSManaged public var localStartDate: NSDate?
    @NSManaged public var localEndDate: NSDate?
    @NSManaged public var duration: Int64
    @NSManaged public var speed: Double
    @NSManaged public var _id: Int64
    @NSManaged public var sessionUuid: String?
    @NSManaged public var tripUuid: String?


// .这是表示演示对象的 JSON 字符串:

let tripData = "\"id\":26105240,\"userId\":25796277,\"carId\":25817551,\"vehicleId\":57812351,\"sessionUuid\":\"53324259-aa69-41c8-8f9e-c62bdb70f165\",\"tripUuid\":\"afdd8f55-6d14-4cf9-bd9f-5b6da47aaf93\",\"localStartDate\":1487170622490,\"localEndDate\":1487178323654,\"globalStartDate\":1487163422490,\"globalEndDate\":1487171123654,\"routeLocations\":null,\"litres\":24.7699,\"kpl\":0.0772,\"cost\":153.3258,\"distance\":1.9132,\"duration\":491.958,\"speed\":14.0"

// 这里是我试图用来创建这个 Mock 对象的方法:

func makeMockData() 
    let singleTrip = NGTripSummary(json: tripData)
    print("Single Trip: \(singleTrip)")
 

// 现在:当创建对象时,崩溃发生在这里@class EVReflection:

        // Call your own object validators that comply to the format: validate<Key>:Error:
            do 
                var setValue: AnyObject? = value as AnyObject?
/* LINE 923: CRASH HAPPENS HERE -> */  try anyObject.validateValue(&setValue, forKey: key)
                anyObject.setValue(setValue, forKey: key)
             catch _ 
                (anyObject as? EVReflectable)?.addStatusMessage(.InvalidValue, message: "Not a valid value for object `\(NSStringFromClass(type(of: (anyObject as AnyObject))))`, type `\(type)`, key  `\(key)`, value `\(value)`")
                print("INFO: Not a valid value for object `\(NSStringFromClass(type(of: (anyObject as AnyObject))))`, type `\(type)`, key  `\(key)`, value `\(value)`")
            

/////////////////////////////////////////////////////////////

[error] 错误:CoreData:错误:无法调用 NSManagedObject 类 'NGTripSummary' 上的指定初始化程序 CoreData:错误:CoreData:错误:无法在 NSManagedObject 类 'NGTripSummary' 上调用指定的初始化程序

/////////////////////////////////////// ///

->任何人,请帮助:-0

【问题讨论】:

【参考方案1】:

错误消息描述了确切的问题。您似乎正在使用这行代码创建NGTripSummary 的实例:

let singleTrip = NGTripSummary(json: tripData)

但是NGTripSummaryNSManagedObject 的子类,并且您永远不会为NSManagedObject 调用指定的初始化程序。这是必需的。您必须在NSManagedObject 上调用init(entity:insertInto:),或者在NSEntityDescription 上使用工厂方法insertNewObject(forEntityName:into:) 来获取有效的托管对象。否则,您会收到此特定错误,并且您的应用会崩溃。

如果您需要使用tripData 创建实例,您可以这样做,但您还需要提供托管对象上下文和实体描述。你可以在你的类上使用一个便利的初始化器来做到这一点,它会在初始化过程中调用指定的初始化器。

【讨论】:

嗨@Tom Harrington,您能提供一个指定初始化程序的示例吗?/谢谢 @HernanArber 每个类都有一个指定的初始化程序,对于NSManagedObject,这是我在回答中提到的。如果您不确定指定初始化程序是什么,请查看 Apple 的 documentation on class initialization in Swift。【参考方案2】:

EVReflection 现在有一个用于 CoreData 的 Cocoapods 子规范。欲了解更多信息,请参阅https://github.com/evermeer/EVReflection/tree/master/Source/CoreData

它会让你编写这样的代码:\

let moc: NSManagedObjectContext = EVReflectionTestsData().moc // Your code for getting the NSManagedObjectContext.

let obj = CoreDataPerson(context: moc, json: "\"firstName\" : \"Edwin\", \"lastName\" : \"Vermeer\"")

try! moc.save() //TODO: implement error handling

【讨论】:

以上是关于带有 NSManagedObject 的 EVReflection 崩溃/不工作的主要内容,如果未能解决你的问题,请参考以下文章

iOS Swift Core Data 生成带有项目命名空间的 NSManagedObject

带有 NSManagedObject 的 EXC_BAD_ACCESS

NSJSONSerialization 不解析 NSManagedObject

NSFetchedResultsController/NSFetchRequest 与 NSManagedObject 的多对多关系

将获取的 NSManagedObject 分配给属性

托管对象之外的 NSManagedObject 子类作为普通对象