在Xcode 6b3上使用Swift时,我只是简单地插入一个具有一对一关系的NSManagedObject。
我放了我的repro on GitHub,但失败的代码(在SwiftCoreDataRelationshipReproTests.swift
的{{1}}单元测试方法中)归结为:
testSwiftToOne
这似乎应该有效。没有什么棘手的。
我可以使用Swift正确地插入(并保存)具有to-many关系的非常相似的let momURL : NSURL = NSBundle.mainBundle().URLForResource("SwiftCoreDataRelationshipRepro",
withExtension: "momd")
let mom : NSManagedObjectModel = NSManagedObjectModel(contentsOfURL: momURL)
let psc : NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: mom);
let ps : NSPersistentStore = psc.addPersistentStoreWithType(
NSInMemoryStoreType,
configuration: nil,
URL: nil,
options: nil,
error: nil)
let moc : NSManagedObjectContext = NSManagedObjectContext()
moc.persistentStoreCoordinator = psc
// This throws an NSInvalidArgumentException: "An NSManagedObject of class 'NSManagedObject' must have a valid NSEntityDescription."
NSManagedObject(
entity: NSEntityDescription.entityForName("Pet", inManagedObjectContext: moc),
insertIntoManagedObjectContext: moc)
实体(如通过Person
测试中所证明的那样)。更复杂的Objective-C版本也可以使用相同的数据模型(通过testSwiftToMany
测试)成功。
以下是完整的例外情况:
testObjcToOneAndToMany
答案 0 :(得分:7)
所以我无法解决问题,但我认为我将其缩小到框架或Swift中的错误。使用entityForName
相当于将实体直接从managedObjectModel中取出,所以我试着这样做:
let entities = moc.persistentStoreCoordinator.managedObjectModel.entitiesByName;
let keys = Array(entities.keys)
let petVar : String = keys[1] as String
let isEqual1 = (petVar == "Pet") // true
let isEqual2 = (petVar.hashValue == "Pet".hashValue) // true
let result1 = entities["Pet"] // nil
let result2 = entities[petVar] // non-nil
let result3 = entities.bridgeToObjectiveC().objectForKey("Pet".bridgeToObjectiveC()) // nil
let result4 = entities.bridgeToObjectiveC().objectForKey(petVar.bridgeToObjectiveC()) // non-nil
// Doesn't Pass
XCTAssertNotNil(NSEntityDescription.entityForName("Pet", inManagedObjectContext: moc));
// Passes
XCTAssertNotNil(NSEntityDescription.entityForName(petVar, inManagedObjectContext: moc));
它适用于从字典中拔出的键,但不是与键相同的字符串(即使哈希值相同)。
我认为这绝对表明框架或Swift本身存在错误。我正在运行Xcode(6b3)和10.9.4
我认为是时候报告错误了。