如何在CoreData中将相关对象从一个对象移动到另一个对象

时间:2014-09-19 09:06:28

标签: ios objective-c core-data

我在CoreData中遇到一些数据库操作的麻烦。有时视图会在过程中间刷新并显示错误的状态。有时甚至会丢失数据。

我有以下CoreData对象模型:

课程有很多学生

现在我想将两门课程A和B合并在一起,以便之后B课程的所有学生都应该被分配到课程A而课程B不再存在。

(一名学生只参加一门课程)

目前我这样做,大部分时间都有效,但有所描述的问题:

Course courseA = [self someCourse];
Course courseB = [self someOtherCourse];

for (Student *student in courseB.students) {
    student.course = courseA;
}

[managedObjectContext deleteObject:courseB];

NSError *error = nil;
[managedObjectContext save:&error];
if(error != nil) {
    NSLog(@"Deletion of Course failed.");
}

有时我在设备日志中收到以下错误:

Core Data: warning: validation recovery attempt FAILED with Error Domain=NSCocoaErrorDomain Code=1550 "The operation couldn’t be completed. (Cocoa error 1550.)" UserInfo=0x1d97f8e0 {NSLocalizedDescription=The operation couldn’t be completed. (Cocoa error 1550.), Dangling reference to an invalid object.=null, NSValidationErrorObject=<Course: 0x1cad56c0> (entity: Course; id: 0x1ca69380 <x-coredata:///Course/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D3519> ; data: {
    endDateTime = "2014-09-18 17:38:17 +0000";
    place = "0x1db4c120 <x-coredata:///Place/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D7394>";
    room = "0x18d696a0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Room/p1>";
    category = "0x18e8f990 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/CDCategory/p1>";
    changed = "2014-09-19 08:04:03 +0000";
    startDateTime = "2014-09-18 17:30:01 +0000";
    syncInfos = "<relationship fault: 0x1cbb5bb0 'syncInfos'>";
    students =     (
        "0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393>",
        "0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383>",
        "0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461401>",
        "0x1a0a6560 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461387>",
        "0x1c90e2f0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461346>",
        "0x1cd7fc00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461370>",
        "0x1a0bdbf0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461374>",
        "0x1cb11090 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461395>",
        "0x1cf31fc0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461379>",
        "0x1cda6230 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461339>",
        "(...and 133 more...)"
    );
}), NSAffectedObjectsErrorKey=(
    "<Student: 0x1cf6c000> (entity: Student; id: 0x1a36fc70 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461431> ; data: <fault>)"
), NSValidationErrorKey=students, NSValidationErrorValue=Relationship 'students' on managed object (0x1cad56c0) <Course: 0x1cad56c0> (entity: Course; id: 0x1ca69380 <x-coredata:///Course/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D3519> ; data: {
    endDateTime = "2014-09-18 17:38:17 +0000";
    place = "0x1db4c120 <x-coredata:///Place/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D7394>";
    room = "0x18d696a0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Room/p1>";
    category = "0x18e8f990 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/CDCategory/p1>";
    changed = "2014-09-19 08:04:03 +0000";
    startDateTime = "2014-09-18 17:30:01 +0000";
    syncInfos = "<relationship fault: 0x1cbb5bb0 'syncInfos'>";
    students =     (
        "0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393>",
        "0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383>",
        "0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461401>",
        "0x1a0a6560 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461387>",
        "0x1c90e2f0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461346>",
        "0x1cd7fc00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461370>",
        "0x1a0bdbf0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461374>",
        "0x1cb11090 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461395>",
        "0x1cf31fc0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461379>",
        "0x1cda6230 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461339>",
        "(...and 133 more...)"
    );
}) with objects {(
    <Student: 0x1d9e48d0> (entity: Student; id: 0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393> ; data: <fault>),
    <Student: 0x1ddc6920> (entity: Student; id: 0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383> ; data: <fault>),
    <Student: 0x1d991750> (entity: Student; id: 0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461455> ; data: <fault>),
    <Student: 0x1cf6c000> (entity: Student; id: 0x1a36fc70 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461431> ; data: <fault>)
)}, NSValidationErrorShouldAttemptRecoveryKey=true} and {
    "Dangling reference to an invalid object." = "<null>";
    NSAffectedObjectsErrorKey =     (
        "<Student: 0x1cf6c000> (entity: Student; id: 0x1a36fc70 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461431> ; data: <fault>)"
    );
    NSLocalizedDescription = "The operation couldn\U2019t be completed. (Cocoa error 1550.)";
    NSValidationErrorKey = students;
    NSValidationErrorObject = "<Course: 0x1cad56c0> (entity: Course; id: 0x1ca69380 <x-coredata:///Course/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D3519> ; data: {\n    endDateTime = \"2014-09-18 17:38:17 +0000\";\n    place = \"0x1db4c120 <x-coredata:///Place/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D7394>\";\n    room = \"0x18d696a0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Room/p1>\";\n    category = \"0x18e8f990 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/CDCategory/p1>\";\n    changed = \"2014-09-19 08:04:03 +0000\";\n    startDateTime = \"2014-09-18 17:30:01 +0000\";\n    points = 1436;\n    done = 1;\n    notes = \"\";\n    syncInfos = \"<relationship fault: 0x1cbb5bb0 'syncInfos'>\";\n    students =     (\n        \"0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393>\",\n        \"0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383>\",\n        \"0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461401>\",\n        \"0x1a0a6560 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461387>\",\n        \"0x1c90e2f0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461346>\",\n        \"0x1cd7fc00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461370>\",\n        \"0x1a0bdbf0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461374>\",\n        \"0x1cb11090 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461395>\",\n        \"0x1cf31fc0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461379>\",\n        \"0x1cda6230 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461339>\",\n        \"(...and 133 more...)\"\n    );\n})";
    NSValidationErrorShouldAttemptRecoveryKey = 1;
    NSValidationErrorValue = "Relationship 'students' on managed object (0x1cad56c0) <Course: 0x1cad56c0> (entity: Course; id: 0x1ca69380 <x-coredata:///Course/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D3519> ; data: {\n    endDateTime = \"2014-09-18 17:38:17 +0000\";\n    place = \"0x1db4c120 <x-coredata:///Place/tA8FBABB4-2BBD-4A5D-ADFA-94D6F08F6A6D7394>\";\n    room = \"0x18d696a0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Room/p1>\";\n    category = \"0x18e8f990 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/CDCategory/p1>\";\n    changed = \"2014-09-19 08:04:03 +0000\";\n    startDateTime = \"2014-09-18 17:30:01 +0000\";\n    points = 1436;\n    done = 1;\n    notes = \"\";\n    syncInfos = \"<relationship fault: 0x1cbb5bb0 'syncInfos'>\";\n    students =     (\n        \"0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393>\",\n        \"0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383>\",\n        \"0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461401>\",\n        \"0x1a0a6560 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461387>\",\n        \"0x1c90e2f0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461346>\",\n        \"0x1cd7fc00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461370>\",\n        \"0x1a0bdbf0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461374>\",\n        \"0x1cb11090 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461395>\",\n        \"0x1cf31fc0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461379>\",\n        \"0x1cda6230 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461339>\",\n        \"(...and 133 more...)\"\n    );\n}) with objects {(\n    <Student: 0x1d9e48d0> (entity: Student; id: 0x18d073c0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461393> ; data: <fault>),\n    <Student: 0x1ddc6920> (entity: Student; id: 0x1c911b00 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461383> ; data: <fault>),\n    <Student: 0x1d991750> (entity: Student; id: 0x1c915770 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461433> ; data: <fault>),\n    <Student: 0x1dbb38f0> (entity: Student; id: 0x1c920ba0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461435> ; data: <fault>),\n    <Student: 0x1cf7b780> (entity: Student; id: 0x1c9298f0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461436> ; data: <fault>),\n    <Student: 0x1dd3f4f0> (entity: Student; id: 0x1a09a3b0 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461454> ; data: <fault>),\n    <Student: 0x1d9e4850> (entity: Student; id: 0x1cbbe040 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461455> ; data: <fault>),\n    <Student: 0x1cf6c000> (entity: Student; id: 0x1a36fc70 <x-coredata://16CBD0F6-B399-4A9C-BD51-5EC98BD99EFC/Student/p461431> ; data: <fault>)\n)}";
}.

2 个答案:

答案 0 :(得分:2)

你在Student.course的relationShip定义中有什么样的删除规则(可能是:“没有动作”。我认为它应该是“Nullify”)。 悬挂对无效对象的引用通常与技术上不正确设置关系有关。而且还要确保我会在for循环中添加:courseB.students。 copy

答案 1 :(得分:1)

如果只出现问题,在处理更改时重新加载视图,则可以选择缓存数据并同步读取和写入步骤,和/或仅在稳定状态下刷新视图(因此迁移方法完成后发送通知。)

如果它也出现在其他状态,您应该检查模型中的选项(同步,验证,删除规则)或尝试先保存已迁移的学生,然后删除。

如果仍然无效,您能提供模型和关系的屏幕截图吗?

顺便说一句,为什么要迭代每个用户而不是使用

[courseB addStudents:courseA.students];

?当然,只有当你拥有CoreDataGeneratedAccessors时才会出现这种情况:

@interface Course (CoreDataGeneratedAccessors)

- (void)addStudentsObject:(Student *)value;
- (void)removeStudentsObject:(Student *)value;
- (void)addStudents:(NSSet *)value;
- (void)removeStudents:(NSSet *)value;

@end