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

时间:2010-10-19 08:53:13

标签: iphone objective-c cocoa-touch core-data

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


故事(对象)

  • 属性: 创立日期, 顺序,

  • 关系: 句子(一对多与句子)

句子(对象)

  • 属性:图片,订单,文字

  • 关系:belongsTo(与故事一对一)


注意:

  • 句子关系是NSSet
  • belongsTo关系是故事

简单地说,一个故事有很多句子,但句子只能属于一个故事。

我无法有效地设置belongsTo属性 - 而且我知道我错过了一些范例。我担心当我设置belongsTo时,我将使用它自己的NSSet创建另一个Story对象,创建一个递归的doom循环。无论如何,我的问题似乎是有效地设置每个句子的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集的插入吗?

供参考: Sentence.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

Sentence.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

story.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

story.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 个答案:

答案 0 :(得分:1)

我对你为什么直接在Story上调用alloc / init感到有点困惑。我怀疑如果你在你的代码中的其他地方做同样的事情(你应该为我们发布的那些内容),那么传入addStoryItemAction的“sentence”对象可能不是一个正确初始化的NSManagedObject。

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

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