CoreData 关系澄清:如何有效地设置反向关系

Posted

技术标签:

【中文标题】CoreData 关系澄清:如何有效地设置反向关系【英文标题】:CoreData Relationships Clarification: How to effectively set an inverse relationship 【发布时间】:2010-10-19 08:53:13 【问题描述】:

我有一个 CoreData 关系设置如下: (对不起,我是 *** 的新手,所以我必须用 ascii 来绘制它)。


故事(对象)

属性: 创立日期, 顺序,

关系: 句子(用句子一对多)

句子(对象)

属性:图片、顺序、文字

关系:belongsTo(与 Story 一对一)


注意事项:

句子关系是一个 NSSet belongsTo 关系是一个故事

简单来说,一个 Story 有很多 Sentence,但一个 Sentence 只能属于一个 Story。

我在有效设置 belongsTo 属性时遇到了麻烦 - 我知道我有点错过了范式。恐怕当我设置 belongsTo 时,我会用它自己的 NSSet 创建另一个 Story 对象,从而创建一个厄运的递归循环。无论如何,我的问题似乎是有效地设置了每个句子的 belongsTo 属性/关系。

将我的数据插入 CoreData 存储库的代码如下所示:

-(void)addStoryItemAction:(Sentence*)sentence

[self dismissModalViewControllerAnimated:YES];  
Story *story = [[Story alloc] initWithSentence: sentence];

sentence.belongsTo = story;

//crash and burn here.

Story *storySetter = (Story*)   [NSEntityDescription insertNewObjectForEntityForName:@"Story" inManagedObjectContext:managedObjectContext];
[storySetter setSentences:      story.sentences];
[storySetter setCreationDate:   story.creationDate];
[storySetter setOrder:          story.order];

NSError *error;  

BOOL isSaved = [managedObjectContext save:&error];
NSLog(@"isSaved? %@", (isSaved ? @"YES" :@"NO ") );

if (!isSaved) 
    NSLog(@"%@:%s Error saving context: %@", [self class], _cmd, [error localizedDescription]);
    return;

运行时出现以下错误:

-[Sentence setBelongsTo:]:无法识别的选择器发送到实例 0x5b5aa00

我知道我在路上的某个地方遗漏了要点 - 有人可以澄清我哪里出错了,以便我可以有效地实现这个 CoreData 集的插入吗?

仅供参考: 句子.h:

 #import <Foundation/Foundation.h>
 #import "Story.h"

 @class Story;

 @interface Sentence : NSManagedObject 
 
 @property (assign) NSString  *text;
 @property (assign) NSString  *image;
 @property (assign) NSInteger *order;
 @property (nonatomic, retain) Story  *belongsTo;

 - (id)initWithContent:(NSString*)sentenceText image:(NSString*)sentenceImage order: (NSInteger*)sentencePosition;
 @end

句子.m:

 #import "Sentence.h"
 @implementation Sentence
 @synthesize text;
 @synthesize image;
 @synthesize order;
 @dynamic belongsTo;

 - (id)initWithContent:(NSString*)sentenceText image:(NSString*)sentenceImage order: (NSInteger*)sentencePosition
[self setText:  sentenceText];
[self setImage: sentenceImage];
[self setOrder: sentencePosition];  
return self;
 
 @end

故事.h

 #import <Foundation/Foundation.h>
 #import <CoreData/CoreData.h>
 #import "Sentence.h" 
 @class Sentence;
 @interface Story : NSManagedObject 
 
 @property (assign) NSSet     *sentences;
 @property (assign) NSDate    *creationDate;
 @property (assign) NSInteger *order;

 - (id)initWithSentence:(Sentence*)sentence;
 @end

故事.m

 #import "Story.h"
 @implementation Story
 @synthesize sentences;
 @synthesize creationDate;
 @synthesize order;

 - (id)initWithSentence: (Sentence*) sentence

NSLog(@"initWithSencence: sentence: %@", sentence);
sentences = [[NSSet alloc] initWithObjects:sentence, nil];
//[sentences setByAddingObject:sentence];
[self setSentences:sentences];
NSLog(@"sentences (in story object): %@", sentences);
creationDate = [NSDate date];
[self setCreationDate:creationDate];
//later expansion, position should be max(position of all stories) ++
[self setOrder:0];

 return self;
 

 @end

【问题讨论】:

【参考方案1】:

我对你为什么直接在 Story 上调用 alloc / init 感到有点困惑。我怀疑如果你在代码的其他地方做同样的事情(你应该发布给我们看)然后传递给 addStoryItemAction: 的“句子”对象可能不是一个正确初始化的 NSManagedObject。

您遇到的错误意味着基础类没有正确实现该属性“belongsTo”的访问器,因此您的初始化代码中似乎有问题。你应该使用:

NSEntityDescription *entityFromModel = [[aModel entitiesByName] valueForKey:@"Sentence"];
Sentence *sentence = (Sentence *)[[NSManagedObject alloc] initWithEntity:entityFromModel insertIntoManagedObjectContext:context];

【讨论】:

嗨 IHW,感谢您的回答。几天之内我将没有机会尝试您的答案,但我期待看到答案是否能解决我出错的地方。与此同时,正如你所要求的,我已经添加了额外的相关代码 - 希望能澄清一点。再次干杯! 通过查看实现文件,您肯定缺少对 NSManagedObject 的指定初始化程序 initWithEntity:insertIntoManagedObjectContext 的调用。一个合适的补救措施(如果您仍想使用这些包装器)将更改它们以采用托管对象上下文参数并调用 [super initWithEntity:anEntityDescription insertIntoManagedObjectContext:passedInContext]。 感谢 IHW,我使用了 initWithEntity 语句而不是我自己的初始化程序,现在我工作正常。感谢您的回答!

以上是关于CoreData 关系澄清:如何有效地设置反向关系的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Coredata 中的相同实体之间创建多个关系?

CoreData 关系混乱

CoreData 困境:没有反向关系的实体

将两个 CoreData 关系(具有反向关系)分配给同一个实体

Core Data 关系的自定义设置器以强制反向互惠关系

Coredata关系实体创建