核心数据关系:如何将新对象插入到实体中,并与另一个实体中的现有对象build立关系

我正在构build一个小的iPhone应用程序,它允许用户保持与朋友一起玩游戏的分数。 我现在需要在核心数据中使用关系,但似乎无法使其工作。

我希望能够将新数据添加到一个实体中,同时创build与另一个实体中现有数据的关系。 我怎样才能做到这一点?

请注意我是Core Data的新手,并且花费了今天最好的一部分来解决这个问题,但运气不佳。 任何帮助将非常感激。


我有3个实体: 分数游戏玩家

分数属性: dateplayer1Scoreplayer2Scorestatus

游戏属性: title

玩家属性: name

我有许多关系( 比赛 “—” 游戏 )和( 得分 << — >> 玩家


我已经有了一个游戏和玩家的列表。 用户select哪个游戏和谁在玩,并且利用这个信息,在Scores实体中创build了一组对象,并与所select的游戏和玩家有关系。

这是我的来源:

 // Scores.h #import <Foundation/Foundation.h> #import <CoreData/CoreData.h> @class Games, Players; @interface Scores : NSManagedObject @property (nonatomic, retain) NSDate * date; @property (nonatomic, retain) NSNumber * player1Score; @property (nonatomic, retain) NSNumber * player2Score; @property (nonatomic, retain) NSNumber * status; @property (nonatomic, retain) NSSet *game; @property (nonatomic, retain) NSSet *player; @end @interface Scores (CoreDataGeneratedAccessors) - (void)addGameObject:(Games *)value; - (void)removeGameObject:(Games *)value; - (void)addGame:(NSSet *)values; - (void)removeGame:(NSSet *)values; - (void)addPlayerObject:(Players *)value; - (void)removePlayerObject:(Players *)value; - (void)addPlayer:(NSSet *)values; - (void)removePlayer:(NSSet *)values; @end 

 // SC_ScoreViewController.h #import <UIKit/UIKit.h> @interface SC_ScoreViewController : UIViewController @property (strong) NSIndexPath *game; @property (strong) NSIndexPath *playerOne; @property (strong) NSIndexPath *playerTwo; @property (weak, nonatomic) IBOutlet UILabel *playerOneName; @property (weak, nonatomic) IBOutlet UILabel *playerTwoName; @end 

 // SC_ScoreViewController.m #import "SC_ScoreViewController.h" #import "Scores.h" #import "Players.h" #import "Games.h" @interface SC_ScoreViewController () @end @implementation SC_ScoreViewController @synthesize game; @synthesize playerOne; @synthesize playerTwo; // managedObjectContext (context) - (NSManagedObjectContext *)managedObjectContext { NSManagedObjectContext *context = nil; id delegate = [[UIApplication sharedApplication] delegate]; if ([delegate respondsToSelector:@selector(managedObjectContext)]) { context = [delegate managedObjectContext]; } return context; } - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; if (self) { // Custom initialization } return self; } - (void)viewDidLoad { [super viewDidLoad]; // Setup Nav Title self.navigationItem.title = [self.game valueForKey:@"title"]; // Setup Player's Names [self.playerOneName setText:[self.playerOne valueForKey:@"name"]]; [self.playerTwoName setText:[self.playerTwo valueForKey:@"name"]]; Scores * newEntry = [NSEntityDescription insertNewObjectForEntityForName:@"Scores" inManagedObjectContext:self.managedObjectContext]; newEntry.player1Score = 0; newEntry.player2Score = 0; newEntry.status = nil; newEntry.player = self.playerOne; // Incompatible pointer types assigning to NSSet from NSIndexPath NSError *error; if (![self.managedObjectContext save:&error]) { NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 

我希望我已经清楚,并提供了足够的信息。 这是我的第一个问题,所以我希望一切都是为了。 任何帮助将是惊人的,谢谢。

你必须将Players的对象插入到self.managedObjectContext ,就像插入一个新的Score对象一样。 这可能是这样的:

 Scores *score = [NSEntityDescription insertNewObjectForEntityForName:@"Scores" inManagedObjectContext:self.managedObjectContext]; Player *player = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:self.managedObjectContext]; [score addPlayerObject:player]; 

你也必须改变你的关系“分数<< —”玩家“要下令,因为现在你不会知道哪个玩家是哪个。 其他的select是使用两个多对一的关系(分别为player1和player2)。

还有一件事:以单数forms命名实体是一种最​​佳做法,所以Score ,而不是Scores等等。

您应该阅读创build托pipe对象关系 。 这里面都有很好的描述。

更新:我认为不应该有一个游戏和分数之间的多对多关系(从我所了解的分数可以重新命名为匹配)。 这可能应该是一个一对多的关系。

你可能会考虑重新devise你的对象图。 从现实来看,我的头脑中有一个概念,就是游戏,玩家和分数是如何相互关联的。 然而,你的对象图似乎并不符合这个概念(但你的游戏,玩家和分数如何相互关联的概念可能与我的不同)。

我会消除所有这些多对多的关系,并用一对多的关系来取代它们。 例如,玩家可以有很多分数,但分数不会有很多玩家。 三名球员可能有100分,但这并不意味着他们共享一个单一的得分对象(值为100)。

以下是我可能如何devise对象图:

游戏实体:

  • 标题属性(例如“垄断”)
  • 玩家关系,一对多(一个游戏,很多玩家)

玩家实体:

  • 名字属性(例如,Joe Smith)
  • 游戏关系,一对多(一个玩家,很多游戏)
  • 分数关系,一对多(一名球员,很多分数)

得分实体:

  • 分数属性,int值(例如100)
  • 游戏关系,一对一(一个分数,一个游戏)

devise你的模型的另一种方法是如下所示:

游戏 – 代表游戏types的对象(垄断,网球等)

匹配 – 实际的“游戏”,发生在某个时间点,具有date/时间或时间段等属性。 加上player1,player2等…谁真正参加了。 加上每个球队或球员得分例如player1Score,player2Score …

竞争对手 – 或玩家。