【问题标题】:Inserting an NSManagedObject in Swift with a To-One Relationship在 Swift 中插入一个具有一对一关系的 NSManagedObject
【发布时间】:2014-07-11 01:46:20
【问题描述】:

在 Xcode 6b3 上使用 Swift 时,我无法简单地插入具有一对一关系的 NSManagedObject。

我输入了我的repro on GitHub,但失败的代码(在SwiftCoreDataRelationshipReproTests.swifttestSwiftToOne 单元测试方法中)归结为:

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 实体可以使用 Swift 正确插入(并保存)(如通过 testSwiftToMany 测试所证明的那样)。更复杂的 Objective-C 版本也成功地使用了相同的数据模型(通过 testObjcToOneAndToMany 测试)。

这是整个例外情况:

file:///%3Cunknown%3E: test failure: -[SwiftCoreDataRelationshipReproTests testSwiftToOne()] failed: failed: caught "NSInvalidArgumentException", "An NSManagedObject of class 'NSManagedObject' must have a valid NSEntityDescription."
(
    0   CoreFoundation                      0x00007fff8dd6525c __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x00007fff84ce5e75 objc_exception_throw + 43
    2   CoreData                            0x00007fff8765dd16 -[NSManagedObject initWithEntity:insertIntoManagedObjectContext:] + 550
    3   SwiftCoreDataRelationshipReproTests 0x0000000100394d4a _TTOFCSo15NSManagedObjectcfMS_FT6entityGSQCSo19NSEntityDescription_30insertIntoManagedObjectContextGSQCSo22NSManagedObjectContext__S_ + 42
    4   SwiftCoreDataRelationshipReproTests 0x00000001003946bd _TFCSo15NSManagedObjectCfMS_FT6entityGSQCSo19NSEntityDescription_30insertIntoManagedObjectContextGSQCSo22NSManagedObjectContext__S_ + 93
    5   SwiftCoreDataRelationshipReproTests 0x0000000100393450 _TFC35SwiftCoreDataRelationshipReproTests35SwiftCoreDataRelationshipReproTests14testSwiftToOnefS0_FT_T_ + 816
    6   SwiftCoreDataRelationshipReproTests 0x00000001003934c2 _TToFC35SwiftCoreDataRelationshipReproTests35SwiftCoreDataRelationshipReproTests14testSwiftToOnefS0_FT_T_ + 34
    7   CoreFoundation                      0x00007fff8dc50a5c __invoking___ + 140
    8   CoreFoundation                      0x00007fff8dc508c4 -[NSInvocation invoke] + 308
    9   XCTest                              0x00000001003b023a -[XCTestCase invokeTest] + 253
    10  XCTest                              0x00000001003b03ac -[XCTestCase performTest:] + 142
    11  XCTest                              0x00000001003b8ad0 -[XCTest run] + 257
    12  XCTest                              0x00000001003af68b -[XCTestSuite performTest:] + 379
    13  XCTest                              0x00000001003b8ad0 -[XCTest run] + 257
    14  XCTest                              0x00000001003af68b -[XCTestSuite performTest:] + 379
    15  XCTest                              0x00000001003b8ad0 -[XCTest run] + 257
    16  XCTest                              0x00000001003af68b -[XCTestSuite performTest:] + 379
    17  XCTest                              0x00000001003b8ad0 -[XCTest run] + 257
    18  XCTest                              0x00000001003acc8f __25-[XCTestDriver _runSuite]_block_invoke + 56
    19  XCTest                              0x00000001003b773d -[XCTestObservationCenter _observeTestExecutionForBlock:] + 162
    20  XCTest                              0x00000001003acbc8 -[XCTestDriver _runSuite] + 269
    21  XCTest                              0x00000001003ad34a -[XCTestDriver _checkForTestManager] + 551
    22  XCTest                              0x00000001003bb879 +[XCTestProbe runTests:] + 175
    23  Foundation                          0x00007fff8e0aacb7 __NSFireDelayedPerform + 333
    24  CoreFoundation                      0x00007fff8dccc494 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 20
    25  CoreFoundation                      0x00007fff8dccbfcf __CFRunLoopDoTimer + 1151
    26  CoreFoundation                      0x00007fff8dd3d5aa __CFRunLoopDoTimers + 298
    27  CoreFoundation                      0x00007fff8dc87755 __CFRunLoopRun + 1525
    28  CoreFoundation                      0x00007fff8dc86f25 CFRunLoopRunSpecific + 309
    29  HIToolbox                           0x00007fff8e566a0d RunCurrentEventLoopInMode + 226
    30  HIToolbox                           0x00007fff8e566685 ReceiveNextEventCommon + 173
    31  HIToolbox                           0x00007fff8e5665bc _BlockUntilNextEventMatchingListInModeWithFilter + 65
    32  AppKit                              0x00007fff8538e26e _DPSNextEvent + 1434
    33  AppKit                              0x00007fff8538d8bb -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 122
    34  AppKit                              0x00007fff853819bc -[NSApplication run] + 553
    35  AppKit                              0x00007fff8536c7a3 NSApplicationMain + 940
    36  SwiftCoreDataRelationshipRepro      0x000000010000ad55 top_level_code + 37
    37  SwiftCoreDataRelationshipRepro      0x000000010000ad8a main + 42
    38  libdyld.dylib                       0x00007fff861115fd start + 1
)

【问题讨论】:

  • 感谢Dave DeLong,我已将其缩小到NSEntityDescription.entityForName("Pet", inManagedObjectContext: moc) 返回nil。我更新了 GitHub 项目以更好地说明我的失败。另外:我在 10.9.3。
  • 对于它的价值,我在 Xcode 6.0b3 和 OS X 10.9.4 下看到了完全相同的东西。
  • 托尼:感谢您在您的系统上复制此内容。有助于排除这只是我系统上的怪异现象。
  • Dave DeLong 无法在他的 10.10 系统上重现该问题。我刚刚尝试过,并且可以确认我的 MacBook Air 使用相同版本的 Xcode (6b3) 运行 10.10 Preview 3 (14A283o) 上的所有测试都通过了。

标签: core-data swift


【解决方案1】:

所以我无法解决问题,但我认为我将其缩小为框架或 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

我认为是时候报告错误了。

【讨论】:

  • 谢谢,很好的侦探!你能告诉我keys 是什么吗?和/或如果你觉得雄心勃勃,将你传递的解决方法放入 GitHub 拉取请求中? :)
  • 当然!抱歉,我忘了包含中间键变量。是的,我将提交一个包含传递修复的拉取请求
  • 这个错误现在似乎在 XCode 6.0 (6A313) 中得到修复。
猜你喜欢
  • 2018-06-25
  • 1970-01-01
  • 2014-07-12
  • 2020-08-07
  • 2018-06-27
  • 2013-01-12
  • 1970-01-01
  • 2019-07-10
  • 1970-01-01
相关资源
最近更新 更多