我真的被这两件事困扰了。
我正在尝试做的事情:
- 我的实体很简单。这是一个“记录”。
- 它有一个“名称 (NSString)”和“父项 (relationShip)”
- “父级”连接到其自身,实体“记录”。
好的,现在我想创建“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” block 中。那么一切都很好。记录保存到存储中,我可以从那里读取它。
为什么会发生这种情况?如果我想先创建“parentRecord”,保存它,然后再创建“childRecord”,我该怎么办?
为什么我不能使用以前保存的对象? NSManagedObjectContext 是一样的 - 有什么问题吗?
我对“经典”SQL 已经足够好了,但是 Core Data 正在折磨我的大脑。
谢谢大家。
<小时/>更新:
看,saveContext 没有理由崩溃。这是:
- 创建父实体。
- 将其设置为appDelegate的变量。
- 保存上下文(为家长)。
- 创建子实体。
- 从 appDelegate 的变量中设置parentProperty。应用程序崩溃!
还有:
- 创建父实体。
- 将其设置为appDelegate的变量。
- ///////////保存上下文(针对父级)。
- 创建子实体。
- 从 appDelegate 的变量中设置parentProperty。没有任何崩溃。
- 这次保存上下文。
- 现在一切都很好。
父属性 - 只是属性的名称。它不是 MOM 文件中父级的一些附加设置。
我想做具有层次结构的实体。 Xcode 没有为我创建一些额外的方法 - 只是一个属性。
最佳答案
好吧,听起来你有一个简单的数据模型,如下所示(伪代码):
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];
原因是一对多关系需要一个方法来添加新对象来设置。这不能通过简单的分配来完成。然而, child 只有一个 parent ,因此它可以使用简单的分配。由于关系是相互的,分配给一个对象会自动分配给关系另一侧的对象。
这就是它应该如何工作的。您看到的错误很可能来自于错误的对象模型。如果您有像这样的一对一、必需的关系:
Record{
name:string
parent<--(required)-->Record.child
child<--(required)-->Record.parent
}
...当您尝试保存时,如果父项或子项缺失,您将会遇到问题。同样,如果您尝试将多个对象分配给一对一关系,您可能会收到所看到的错误。
在执行插入时,永远不应该使用强制转换,因为如果分配的类和强制转换类之间不匹配,运行时将强制另一个类进行强制转换,从而导致各种奇怪的错误。
我无法确切地说出您的问题是什么,因为我看不到您的对象模型。然而,这应该为您指明正确的方向。
关于iphone - 核心数据: Can't Use Previously Saved Object,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4170101/