代码之家  ›  专栏  ›  技术社区  ›  Prody

coredata:“挂起对无效对象的引用。”错误

  •  24
  • Prody  · 技术社区  · 16 年前

    我正在开发一个CocoaTouch应用程序,它使用coredata,并有一些由xcode模型编辑器生成的nspersistentObject子类。

    我注意到,最近,在保存上下文时,我收到一个错误,其中包含以下部分作为用户信息:

    (gdb) po ui {
        "Dangling reference to an invalid object." = <null>;
        NSAffectedObjectsErrorKey = <dump #1 of someObject>;
        NSLocalizedDescription = "Operation could not be completed. (Cocoa error 1550.)";
        NSValidationErrorKey = <someKey pointing to someObject #1>;
        NSValidationErrorObject = <dump #2 of someOtherObject which points to the dump #1 object>;
        NSValidationErrorValue = { <list of someMoreObjects> };
    }
    

    用户信息字典中有其他键。

    我得到的所有转储都是有效的对象,我已经验证了它们。

    NSValidationErrorObject 是具有 NSSet 其中包含转储到 NSAffectedObjectsErrorKey NSValidationErrorValue . 但所有这些对象都是有效的。

    此外,这种情况是随机发生的,有时会发生,有时不会,有时会将列表转储到 nsvalidationErrorValue(nsvalidationErrorValue) 更长,有时更短。

    我不知道为什么会发生这种情况,也不知道究竟是什么错误。有人知道发生了什么事吗?你知道什么会导致这个奇怪的错误吗?

    9 回复  |  直到 16 年前
        1
  •  25
  •   TechZen    16 年前

    这种错误通常是因为当一个对象没有必要的相互关系时,关系设置不正确。对象是“悬空的”,因为对象图表示它应该处于一种关系中,但它只是在空间中悬空,与任何其他对象都没有连接。从内部一致性的角度来看,对象仍然有效,但它不在图中的有效位置。

        2
  •  18
  •   user1270061    14 年前

    这个问题以前有人问过,但我刚碰到。在我的案例中,这并不是因为技术上的关系设置不当。这是由于对象是在不同的上下文中创建的,请注意,不是在不同的线程上,而是在同一线程上的不同上下文。

    因此,如果您使用核心数据的线程做任何事情,请寻找线程问题。

        3
  •  11
  •   Chris    15 年前

    假设你有一张“食谱”和一张“配料”儿童桌。然后,您创建一对多的关系,从配方到配料,也创建一个从配料到配方的反向关系(一对一)。从配方表中指定一个“级联”的删除规则是有意义的,因为如果删除一个配方,也应该删除该成分。但是,如果在成分中一对一关系的删除规则中指定“无操作”,则在尝试删除成分时会出现悬空引用错误。将一对一关系的删除规则更改为“无效”,这样可以纠正问题。

        4
  •  5
  •   p.pad    14 年前

    我知道这是很久以前的事了,但我一直在一个核心数据模型上与这个问题作斗争,这个模型的所有关系都设置为无效。一直收到这些悬而未决的推荐信直到我找到一个 setPrimitiveValue 而不是 setValue 当我在增加关系的时候。小心,在处理关系时,你必须确保你做了正确的事情,让核心数据为你维护关系!

        5
  •  3
  •   DaGaMs    13 年前

    我还有另一个如何引起这个问题的例子:我有一个并发类型为 NSMainQueueConcurrencyType . 在代码的某个地方,我这样做:

    __block MyObjectType1 *obj1;
    [managedObjectContext performBlockAndWait:^{
        obj1 = [NSEntityDescription insertNewObjectForEntityForName:@"Thing" inManagedObjectContext:managedObjectContext];
    }];
    // some other stuff
    [self saveContext];
    __block NSManagedObjectID *object1ID;
    [managedObjectContext performBlockAndWait:^{
        object1ID = [obj1 objectID];
    }];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // do some slow-ish stuff
        [managedObjectContext performBlockAndWait:^{
            // create new object that has a relationship
            NSManagedObject *obj1_copy = [managedObjectContext objectWithID:object1ID];
            MyObjectType2 *obj2 = [NSEntityDescription insertNewObjectForEntityForName:@"OtherThing" inManagedObjectContext:managedObjectContext];
            obj2.relatedThing = obj1_copy;
        }];
        [self saveContext];
    });
    

    结果是 有时 这是失败的。我还是不明白为什么,但我不得不 非临时的 objectID 似乎能做到这一点:

    [context performBlockAndWait:^{
        NSError *error;
        [managedObjectContext obtainPermanentIDsForObjects:@[obj1] error:&error];
        object1ID = obj1.objectID;
    }];
    
        6
  •  1
  •   Terry    13 年前

    我有同样的问题,最后我发现问题是我在两个不同的托管对象上下文之间设置了一个关系。

        7
  •  0
  •   Undo ptrk    11 年前

    我的问题用以下代码解决:

    [[CustomManagedObject managedObjectContext] performBlockAndWait:^{
            NSError *error;
            if (![[CustomManagedObject managedObjectContext] save:&error])
            {
                NSLog(@"Error in Saving: %@", [error.userInfo description]);
            }
        }];
    
        8
  •  0
  •   Saqib Saud    9 年前

    加上最初的答案,可能有两个原因导致崩溃发生。仔细阅读错误描述,在我的例子中,我是在与另一个上下文中的对象建立关系。

        9
  •  0
  •   Community Mohan Dere    9 年前

    我遇到了这个问题,这个问题必须与具有关系的实体的不同(或者更确切地说是一个零)管理的对象上下文有关。在我的例子中,当两个实体都没有管理对象上下文时,我在它们之间创建了一个关系,然后将其中一个实体添加到主运行中心,并假定另一个也将添加到主运行中心。我之所以这么认为,是因为前两条评论是对这个问题的最高答案 SO thread 但最终还是错了。

    因此,经验教训是:如果您将一个实体添加到一个MOC中,那么与之有关系的其他实体不会被拖到MOC中。您还必须将它们添加到主运行中心,否则核心数据将不高兴。