RestKit 在 PUT 请求时抛出 NSInternalInconsistencyException

RestKit throws NSInternalInconsistencyException upon PUT request

当按以下方式发出 PUT 请求时,我的应用程序因 NSInternalInconsistencyException 而崩溃:

我得到的错误

2015-05-27 17:27:17.796 XYZ[17093:2526798] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Cannot add object with entity 'Company' to cache for entity of 'Company''

错误来自这里RKEntityByAttributeCache.m#L333:

 NSAssert([entity isKindOfEntity:self.entity], @"Cannot add object with entity '%@' to cache for entity of '%@'", [entity name], [self.entity name]);

奇怪的是,entityself.entity 对象都有相同的调试描述。所以我不知道这两个实例的 NSEnityDescriptor 可能有何不同。

到目前为止我已经尝试过的事情

我的映射

我确实将我的映射实现为 RKManagedObjectStore 的扩展,如下所示:

extension RKManagedObjectStore{
    var companyMapping: RKEntityMapping{
        let mapping = RKEntityMapping(
            forEntityForName: "Company",
            inManagedObjectStore: self
        )
        mapping.addAttributeMappingsFromArray(
            ["id", "name"]
        )
        mapping.identificationAttributes = ["id"]

        return mapping
    }

    var profileMapping: RKEntityMapping{
        let mapping = RKEntityMapping(
            forEntityForName: "Profile",
            inManagedObjectStore: self
        )
        mapping.addAttributeMappingsFromArray(
            ["id", "content", "language", "profileImageId" ]
        )
        mapping.identificationAttributes = ["id"]
        mapping.addRelationshipMappingWithSourceKeyPath("companies", mapping: companyMapping)

        return mapping
    }
}

数据 I post 到服务器并以相同的格式返回响应:

{
    "content": "XYZ",
    "id": "profile-1",
    "language": "de",
    "companies": [{
        "id": "company-1",
        "name": "Somecompany Inc."
    }]
}

更新NSMangedObectContext

由于这个问题似乎与多个 NSManagedObjectContext 相关,下面是我设置 RestKit 和 MOC 的方法:

init(baseURL: String, dataModelName: String){

    let modelURL = NSBundle.mainBundle().URLForResource(dataModelName, withExtension: "momd")!
    let managedObjectModel = NSManagedObjectModel(contentsOfURL: modelURL)!
    self.managedObjectStore = RKManagedObjectStore(managedObjectModel: managedObjectModel)

    let storePath = RKApplicationDataDirectory().stringByAppendingPathComponent("\(dataModelName).sqlite")

    var error: NSError? = nil
    managedObjectStore.addSQLitePersistentStoreAtPath(storePath,
        fromSeedDatabaseAtPath: nil,
        withConfiguration: nil,
        options: nil,
        error: &error
    )
    if let e = error{
        // Omitted: Delete the SQLite store and re-create it
    }
    managedObjectStore.createManagedObjectContexts()
    managedObjectStore.managedObjectCache = RKInMemoryManagedObjectCache(
        managedObjectContext: managedObjectStore.persistentStoreManagedObjectContext
    )
    objectManager = RKObjectManager(baseURL: NSURL(string: baseURL))
    objectManager.managedObjectStore = managedObjectStore
    objectManager.requestSerializationMIMEType = RKMIMETypeJSON;

    super.init(baseURL: baseURL)

    setupMapping()
}

您必须创建一个 ManagedObjectStore。我怀疑 self 作为参数是否正确。我从你的解释中推断出 self 是 NSManagedObject 的子类,即你想要映射的实体,CompanyProfile 但是你需要一个 RKManagedObjectStore 并将其作为第二个参数传递。

let mapping = RKEntityMapping(
    forEntityForName: "Profile",
    inManagedObjectStore: <pointer to the RKManagedObjectStore>
)

Curiously now, the entity and the self.entity object both have the same debug description.

实体描述的地址必须不同。

当您篡改 RestKit 使用的托管对象上下文时,通常会发生这种情况,因此比较的实体来自 2 个不同的上下文,因此是不同的,或者当您直接从错误的上下文传递托管对象时。