核心数据关系:如何将新对象插入到实体中并创建与另一实体中的现有对象的关系 [英] Core Data Relationships: How to insert a new object into an entity and create a relationship to an existing object in another entity

查看:96
本文介绍了核心数据关系:如何将新对象插入到实体中并创建与另一实体中的现有对象的关系的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在建立一个小小的iPhone应用程式,让使用者保持游戏的分数,他们可能会与朋友一起玩。我现在需要使用Core Data中的关系,但似乎不能使它工作。



我想在一个实体中添加新数据,同时在不同实体中创建与现有数据的关系。如何实现这一点?



请注意,我是Core Data的新用户,并且花了今天最好的一部分,已经用完了运气。任何帮助将非常感激。






我有3个实体:

属性: > date player1Score player2Score 状态



游戏属性: title



玩家属性: name



我有许多关系(分数< < - > 游戏)和(得分< - >> 玩家






我已经有一个游戏和玩家的列表。用户选择哪个游戏和正在玩的游戏,并且利用该信息,在 Scores 实体中创建一组对象,该对象具有与所选游戏和玩家的关系。



这是我的来源:

  // Scores.h 

#import< Foundation / Foundation.h>
#import< CoreData / CoreData.h>

@class游戏,玩家;

@interface评分: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 

#importSC_ScoreViewController.h
#importScores.h
#importPlayers.h
#importGames.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 respondingToSelector:@selector(managedObjectContext)]){
context = [delegate managedObjectContext];
}
return context;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil ];
if(self){
//自定义初始化
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];

//设置导航标题
self.navigationItem.title = [self.game valueForKey:@title];

//设置播放器名称
[self.playerOneName setText:[self.playerOne valueForKey:@name]];
[self.playerTwoName setText:[self.playerTwo valueForKey:@name]];


Scores * newEntry = [NSEntityDescription insertNewObjectForEntityForName:@ScoresinManagedObjectContext:self.managedObjectContext];
newEntry.player1Score = 0;
newEntry.player2Score = 0;
newEntry.status = nil;
newEntry.player = self.playerOne; //从NSIndexPath分配给NSSet的指针类型不兼容

NSError * error;
if(![self.managedObjectContext save:& error]){
NSLog(@Whoops,could not save:%@,[error localizedDescription]);
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
//处理可以重新创建的任何资源。
}

@end






我希望我已经清楚了,并提供了足够的信息。这是我的第一个问题,所以我希望一切顺利。

解决方案

您必须插入玩家对象插入 self.managedObjectContext 与插入新的 Score 对象完全相同。它可以是这样的:

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

您还必须更改您的关系Scores<< --- >> Players订购,因为现在你不知道哪个播放器是哪个。这里的其他选项是使用两个多对一的关系(分别对player1和player2)。



另一件事:这是一个最佳实践,单数形式,因此 Score ,而不是 Scores 等。



您应该阅读核心数据编程中的关系和获取的属性指南



更新:我认为游戏之间不应该有多对多的关系和Scores(从我的理解Score可以重命名为Match)。它可能应该是一对多的关系。


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.

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.


I have 3 entities: Scores, Games and Players.

Scores Attributes: date, player1Score, player2Score and status.

Games Attributes: title.

Players Attributes: name.

I have many to many relationships between (Scores <<--->> Games) and (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 Scores entity with relationships to the chosen game and players.

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.

解决方案

You have to insert Players' objects into self.managedObjectContext exactly the same as you insert a new Score object. It could be something like this:

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

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

You should read Relationships and Fetched Properties in Core Data Programming Guide. 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.

这篇关于核心数据关系:如何将新对象插入到实体中并创建与另一实体中的现有对象的关系的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆