1

我真的被这两件事困住了。

我正在尝试做的事情:

  1. 我的实体很简单。这是一个“记录”。
  2. 它有一个“名称(NSString)”和“父级(relationShip)”
  3. “父”连接到自身,实体“记录”。

好的,现在我要创建“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!

我重新排列了这段代码,所以 *我不在[self saveContext];“parentRecord”中做* 。只需从变量中使用它groupRecord。并将其保存在“childRecord”块中。那么一切都很好。记录保存到存储中,我可以从那里读取它。

为什么会发生?如果我想先创建“parentRecord”,保存它,然后 - “childRecord”,我应该怎么做?

为什么我不能使用以前保存的对象?NSManagedObjectContext 是一样的——怎么了?

我对“经典”SQL 已经足够好,但 Core Data 正在扼杀我的大脑。

谢谢大家。


更新:

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

  1. 创建父实体。
  2. 将其设置为 appDelegate 的变量。
  3. 保存上下文(对于父母)。
  4. 创建子实体。
  5. 从 appDelegate 的变量设置 parentProperty。应用程序崩溃!

和:

  1. 创建父实体。
  2. 将其设置为 appDelegate 的变量。
  3. ///////////保存上下文(为父级)。
  4. 创建子实体。
  5. 从 appDelegate 的变量设置 parentProperty。没有任何崩溃。
  6. 这次保存上下文。
  7. 现在一切都很好。

父属性 - 只是属性的名称。这不是 MOM 文件中父级的一些额外设置。

我想做具有层次结构的实体。并且没有 Xcode 为我创建的其他方法 - 只是一个属性。

4

2 回答 2

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
}

...如果缺少父母或孩子,您在尝试保存时会遇到问题。同样,如果您尝试将多个对象分配给一对一的关系,您可能会看到您看到的错误。

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

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

于 2010-11-14T18:37:24.313 回答
0

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

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

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

于 2010-11-13T02:12:28.030 回答