2013-10-10 18 views
11

我正在構建一個小iPhone應用程序,它允許用戶保留可能與朋友一起玩遊戲的分數。我現在需要在覈心數據中使用關係,但似乎無法讓它工作。核心數據關係:如何在實體中插入新對象並創建與另一個實體中現有對象的關係

我希望能夠在創建與不同實體中的現有數據的關係時將新數據添加到一個實體中。我怎樣才能做到這一點?

請注意我是Core Data的新手,已經花了很多時間試圖弄清楚這一點,但運氣不佳。任何幫助將非常感激。


我有3個實體:比分遊戲玩家

成績屬性:dateplayer1Scoreplayer2Scorestatus

遊戲屬性:title

玩家屬性:name

我有很多要(成績 < < --- >>遊戲)和(成績 < < --- >>玩家


我之間有許多關係已經有一個遊戲和球員的列表。用戶選擇哪個遊戲和誰在玩,並且通過該信息,在與所選遊戲和玩家有關係的實體中創建一組對象。

這裏是我的源:

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

我希望我已經明確和提供足夠的信息。這是我的第一個問題,所以我希望一切都是爲了。任何幫助都會很棒,謝謝。

回答

8

您必須將Players的對象插入self.managedObjectContext與插入新的Score對象完全相同。這可能是這樣的:

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

您也可以改變你的關係「成績< < --- >>玩家」來訂購,因爲現在你將不知道哪個運動員是哪個。這裏的其他選擇是使用兩個多對一的關係(分別爲player1和player2)。

還有一件事:這是一個以單數形式命名實體的最佳實踐,所以Score而不是Scores等等。

您應該閱讀Creating Managed Object Relationships。這裏都有很好的描述。

更新:我覺得不應該有(從我的理解分數可以被重命名爲比賽)遊戲和分數之間的許多一對多的關係。這可能應該是一對多的關係。

+0

嗨,謝謝你這麼快回答。如果你不介意,我有幾個後續問題。看着你的代碼,一個新的玩家將隨着分數一起創建,對嗎?如果是這樣,我的問題是我已經有球員,並希望將他們連接到得分,其他明智的我只是重新創建他們。此外,我擁有多對多的關係,因爲分數可以有多個遊戲,遊戲可以有多個分數,與玩家和分數相同。 –

+0

對不起,我完全不瞭解你的數據模型(你的關係)。至於玩家,我看到你有'self.playerOne'和'self.playerOneName'。它們分別是類型:'NSIndexPath'和'UILabel'。當你使用核心數據關係時,你必須使用NSManagedObject。我認爲你還沒有它們(因爲它們不存在於你的視圖控制器中),這就是爲什麼我用行創建一個新玩家:'Player * player = [NSEntityDescription(...)''。 –

+0

我曾嘗試使用NSManagedObject,但無法讓它工作。我不斷收到錯誤「從NSManageObject分配給NSSet的指針類型不兼容」。我覺得我在這裏錯過了一些東西,我需要哪些代碼來創建我的關係從分數到玩家?我應該爲每個球員使用兩種不同的關係嗎? –

2

你可能會考慮重新設計你的對象圖。從現實來看,我有一個關於遊戲,玩家和分數如何相互關聯的概念。然而,你的對象圖似乎並不符合這個概念(但你的遊戲,玩家和分數如何相互關聯的概念可能與我的不同)。

我會消除所有這些多對多的關係,並用一對多的關係替換它們。例如,玩家可以有很多分數,但是分數不會有很多玩家。三名球員可能有100分,但這並不意味着他們共享一個單一的得分對象(值爲100)。

以下是我會設計的對象圖:

遊戲實體:

  • title屬性(例如, 「大富翁」)
  • 球員的關係,一個一對多(一個遊戲,很多玩家)

球員實體:

  • name屬性(例如,張三)
  • 遊戲的關係,一個一對多(一名球員,許多遊戲)
  • 分數的關係,一個一對多(一名球員,許多分數)

分數實體:

  • 得分屬性,int值(例如,100)
  • 遊戲關係,一對一(一個得分,一個遊戲)
0

另一種方式設計你的模型如下時候想起來: - 是代表遊戲類型的對象(壟斷,網球等)

賽 -

遊戲實際的「遊戲」,它發生在某個時間點,並且具有日期/時間或週期等屬性。加上player1,player2等...誰真正參加過。加上每個球隊或球員得分例如player1Score,player2Score ...

競爭對手 - 或玩家。

相關問題