xcode 核心数据关系:如何将新对象插入实体并创建与另一个实体中现有对象的关系

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19303062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 04:04:37  来源:igfitidea点击:

Core Data Relationships: How to insert a new object into an entity and create a relationship to an existing object in another entity

iphoneiosobjective-cxcodecore-data

提问by Dean Ridgeley

I am building a little iPhone app which allows users to keep score of games they may be playing with friends. I now need to use relationships in Core Data but can't quite seem to get it working.

我正在构建一个小 iPhone 应用程序,它允许用户记录他们可能与朋友一起玩的游戏的分数。我现在需要在 Core Data 中使用关系,但似乎无法让它正常工作。

I want to be able to add new data into one entity while creating a relationship to existing data in a different entity. How can I achieve this?

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

Please note I am new to Core Data and have spent the best part of today trying to figure this out but have run out of luck. Any help would be very much appreciated.

请注意,我是 Core Data 的新手,今天花了大部分时间试图解决这个问题,但运气不佳。任何帮助将不胜感激。



I have 3 entities: Scores, Gamesand Players.

我有 3 个实体:ScoresGamesPlayers

ScoresAttributes: date, player1Score, player2Scoreand status.

分数属性:dateplayer1Scoreplayer2Scorestatus

GamesAttributes: title.

游戏属性:title.

PlayersAttributes: name.

球员属性:name.

I have many to many relationships between (Scores<<--->> Games) and (Scores<<--->> Players)

我在(Scores<<--->> Games)和(Scores<<--->> Players)之间有很多关系



I already have a list of both games and players. The user selects which game and who is playing and with this information a set of objects is created in the Scoresentity with relationships to the chosen game and players.

我已经有游戏和玩家的列表。用户选择哪个游戏和谁在玩,并使用此信息在Scores实体中创建一组对象,这些对象与所选游戏和玩家有关系。

Here is my source:

这是我的来源:

//  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


I hope I have been clear and provided enough information. This is my first question so I hope all is in order. Any help would be amazing, thank you.

我希望我已经清楚并提供了足够的信息。这是我的第一个问题,所以我希望一切顺利。任何帮助都会很棒,谢谢。

回答by Arek Holko

You have to insert Players' objects into self.managedObjectContextexactly the same as you insert a new Scoreobject. It could be something like this:

您必须将Players' 对象插入self.managedObjectContext到与插入新Score对象完全相同的位置。它可能是这样的:

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

You also have to change your relationship "Scores <<--->> Players" to be ordered, because right now you won't know which player is which. Other option here would be to use two many-to-one relationship (separately for player1 and player2).

您还必须更改要订购的“Scores <<--->> Players”关系,因为现在您不知道哪个玩家是哪个。这里的其他选择是使用两个多对一关系(分别用于 player1 和 player2)。

One more thing: it's a best practice to name your entities in a singular form, so Score, instead of Scoresand so on.

还有一件事:最佳做法是以单数形式命名您的实体,所以Score,而不是Scores等等。

You should read Creating Managed Object Relationships. It's all nicely described in there.

您应该阅读创建托管对象关系。这一切都很好地描述在那里。

UPDATE:I think there shouldn't be a many-to-many relationship between Games and Scores (from what I understand Score can be renamed to Match). It probably should be a one-to-many relationship.

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

回答by bilobatum

You might consider re-designing your object graph. From reality, I have a concept in my head of how games, players, and scores relate to one another. Your object graph, however, doesn't seem to match that concept (but your concept of how games, players, and scores relate to each other may be different than mine).

您可能会考虑重新设计您的对象图。从现实来看,我的脑海里有一个关于游戏、玩家和分数如何相互关联的概念。但是,您的对象图似乎与该概念不符(但您对游戏、玩家和分数相互关联的概念可能与我的不同)。

I would eliminate all those many-to-many relationships and replace them with one-to-many relationships. For example, a player can have many scores, but a score wouldn't have many players. Three players might have a score of 100, but that doesn't mean they share a single score object (with the value of 100).

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

Here's how I might design the object graph:

下面是我如何设计对象图:

Game entity:

游戏实体:

  • title attribute (e.g., "Monopoly")
  • players relationship, one-to-many (one game, many players)
  • 标题属性(例如,“垄断”)
  • 玩家关系,一对多(一个游戏,多个玩家)

Player entity:

玩家实体:

  • name attribute (e.g., Joe Smith)
  • games relationship, one-to-many (one player, many games)
  • scores relationship, one-to-many (one player, many scores)
  • 姓名属性(例如,Joe Smith)
  • 游戏关系,一对多(一个玩家,多个游戏)
  • 分数关系,一对多(一个玩家,多个分数)

Score entity:

评分实体:

  • score attribute, int value (e.g., 100)
  • game relationship, one-to-one (one score, one game)
  • score 属性,int 值(例如,100)
  • 博弈关系,一对一(一分,一局)

回答by Duncan Groenewald

Another way to think of it when designing your model is as follows:

设计模型时的另一种思考方式如下:

Game - is an object representing the type of game (monopoly, tennis, etc)

游戏 - 是代表游戏类型(垄断、网球等)的对象

Match - the actual 'game', which takes place at a point in time and has an attribute like date/time or period. Plus player1, player2, etc... Whoever actually took part. Plus each team or players score e.g. player1Score, player2Score...

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

Competitor - or player.

竞争对手 - 或玩家。