核心数据:无法使用以前保存的对象

时间:2010-11-13 00:06:51

标签: iphone cocoa core-data nsmanagedobjectcontext

我真的很困惑这两件事。

我想做什么:

  1. 我的实体很简单。这是一个“记录”。
  2. 它有“name(NSString)”和“parent(relationShip)”
  3. “parent”连接到自身,实体“record”。
  4. 好的,现在我要创建“parentRecord”和“simpleRecord”。

    我尝试使用该代码:

     groupRecord = (record *)[NSEntityDescription insertNewObjectForEntityForName:@"record" 
                                          inManagedObjectContext:self.managedObjectContext];
     groupRecord.name = GroupTextField.text;
     [self saveContext];
    

    它是“parentRecord”,我将其保存以供将来使用,并捕获“groupRecord”变量。

    现在我必须创建一个“simpleRecord”。这是一个代码:

    record *newRecord = (record *)[NSEntityDescription 
           insertNewObjectForEntityForName:@"record" 
           inManagedObjectContext:self.managedObjectContext]; 
    newRecord.name = textField.text;
    [newRecord setMyParent:groupRecord]; //and it crashes here!
    

    我重新安排了此代码,因此* 我在“parentRecord”中没有[self saveContext]; * 。 只需使用变量groupRecord即可。并将其保存在“childRecord”块中。一切都很好。记录保存到存储,我可以从那里读取。

    为什么会这样?我该怎么办,如果我想首先创建“parentRecord”,保存它,以及稍后 - “childRecord”?

    为什么我不能使用以前保存的对象? NSManagedObjectContext是一样的 - 出了什么问题?

    我对“经典”SQL很满意,但核心数据正在扼杀我的大脑。

    感谢大家。


    更新

    看,saveContext没有崩溃的理由。这是:

    1. 创建父实体。
    2. 将其设置为appDelegate的变量。
    3. 保存上下文(针对父母)。
    4. 创建childEntity。
    5. 从appDelegate的变量设置parentProperty。应用程序崩溃了!
      1. 创建父实体。
      2. 将其设置为appDelegate的变量。
      3. ///////////保存上下文(对于父母)。
      4. 创建childEntity。
      5. 从appDelegate的变量设置parentProperty。没有任何崩溃。
      6. 这次保存文字。
      7. 一切都很好。
      8. 父属性 - 只是属性的名称。它不是MOM文件中父级的一些额外设置。

        我想用层次结构做实体。 Xcode为我创建了一些额外的方法 - 只是一个属性。

2 个答案:

答案 0 :(得分:1)

好吧,听起来你有一个看起来像这样的简单数据模型(伪代码):

Record{
    name:string
    parent-->Record
}

这很危险,因为没有互惠关系。这可能导致孤立的对象并损害对象图的完整性。而是使用:

Record{
    name:string
    parent<--(optional)-->Record.child
    child<--(optional)-->Record.parent
}

现在,您有一个简单的一维链表,如数组或集合。除了最顶层的记录对象之外,每个记录对象都有一个父对象,并期望最底层的对象都有一个子对象。要为每个人分配一个:

Record *firstRec; //assuming you have created a custom class for Record
Record *secRec;
firstRec=[NSEntityDescription insertNewObjectForEntityForName:@"Record" 
                                       inManagedObjectContext:self.managedObjectContext];
//-------------------------------------^
secRec=[NSEntityDescription insertNewObjectForEntityForName:@"Record" 
                                       inManagedObjectContext:self.managedObjectContext];
//-------------------------------------^
firstRec.name=someText;
secRec,name=someOtherText;

firstRec.child=secRec;
[self saveContext];

现在,如果您想要一个树结构,其中每个父项可以有多个子项,那么您将拥有如下对象模型:

Record{
    name:string
    parent<--(optional)-->>Record.child
    child<<--(optional)-->Record.parent
}

然后您的插入和作业将更改为:

Record *firstRec;
Record *secRec;
firstRec=[NSEntityDescription insertNewObjectForEntityForName:@"Record" 
                                       inManagedObjectContext:self.managedObjectContext];
//-------------------------------------^
secRec=[NSEntityDescription insertNewObjectForEntityForName:@"Record" 
                                       inManagedObjectContext:self.managedObjectContext];
//-------------------------------------^
firstRec.name=someText;
secRec.name=someOtherText;
[firstRec.addChildObject:secRec];
// or
secRec.parent=firsRec;

[self saveContext];

原因是多对多关系需要一种方法来添加要设置的新对象。通过简单的任务无法做到这一点。但是,孩子只有一个父母,所以它可以使用简单的作业。由于关系是互惠的,因此分配给一个对象会自动分配给关系另一侧的对象。

这就应该如何运作。您看到的错误很可能来自错误的对象模型。如果您有一对一,必需的关系,请执行以下操作:

Record{
    name:string
    parent<--(required)-->Record.child
    child<--(required)-->Record.parent
}

...当您尝试保存父母或子女时,您将遇到问题。同样,如果您尝试将多个对象分配给一对一关系,则可以获得您看到的错误。

在插入时不应该使用强制转换,因为如果指定的类和强制转换类之间不匹配,运行时会强制另一个类进入强制转换,从而导致各种奇怪的错误。

我无法确切地说出你的问题是什么,因为我看不到你的对象模型。但是,这应该指向正确的方向。

答案 1 :(得分:0)

你会分享“saveContext”和“setMyParent”的代码吗?

NSManagedObjectContext具有 - (BOOL)save:(NSError **)错误方法。是在“saveContext”中调用吗?

并且,如果您的关系被称为“父”,那么您应该设置与-addParentObject:...之类的关系,这将在您的Record.h文件中声明。如果您按特定顺序执行操作,Xcode将为您执行此操作。否则,您需要自己编写方法声明。