Основные отношения данных: как вставить новый объект в объект и создать связь с существующим объектом в другом объекте

Я создаю небольшое приложение для iPhone, которое позволяет пользователям вести счет игр, которые они могут играть с друзьями. Теперь мне нужно использовать отношения в Core Data, но не могу заставить его работать.

Я хочу иметь возможность добавлять новые данные в одну сущность, создавая связь с существующими данными в другой сущности. Как я могу достичь этого?

Обратите внимание, что я новичок в Core Data и провел большую часть сегодняшнего дня, пытаясь понять это, но вам не повезло. Любая помощь будет очень оценена.


У меня есть 3 объекта: Оценка, Игры и Игроки.

Оценка Атрибуты: date, player1Score, player2Score и status.

Игры Атрибуты: title.

Игроки Атрибуты: name.

У меня есть много разных отношений между (Scores < --- → Игры) и ( Оценка < < < < < < < < <; --- → Игроки)


У меня уже есть список игр и игроков. Пользователь выбирает, какую игру и кто играет, и с этой информацией набор объектов создается в объекте Scores с отношениями к выбранной игре и игрокам.

Вот мой источник:

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

Надеюсь, я был ясен и предоставил достаточно информации. Это мой первый вопрос, поэтому я надеюсь, что все в порядке. Любая помощь будет потрясающей, спасибо.

Ответ 1

Вам нужно вставить объекты Playersself.managedObjectContext точно так же, как вы вставляете новый объект Score. Это может быть примерно так:

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

Вам также нужно изменить свои отношения "Счетчики < < --- → Игроки", которые будут заказаны, потому что сейчас вы не будете знать, какой игрок является таковым. Другим вариантом здесь будет использование двух отношений "много-к-одному" (отдельно для игроков1 и игрока2).

Еще одна вещь: лучше всего назвать свои сущности в единственной форме, поэтому Score вместо Scores и т.д.

Вы должны прочитать Создание отношений управляемых объектов. Здесь все хорошо описано.

ОБНОВЛЕНИЕ: Я думаю, что не должно быть отношения "многие ко многим" между "Играми и счетами" (из того, что я понимаю, "Score" можно переименовать в Match). Вероятно, это должно быть отношение "один ко многим".

Ответ 2

Вы можете подумать о перепроектировании своего графа объектов. Из реальности у меня есть концепция в моей голове, как игры, игроки и оценки соотносятся друг с другом. Однако ваш графический объект не соответствует этой концепции (но ваша концепция о том, как игры, игроки и оценки соотносятся друг с другом, может отличаться от моего).

Я бы устранил все эти отношения "многие ко многим" и заменил их отношениями "один ко многим". Например, у игрока может быть много очков, но на счету не будет много игроков. У трех игроков может быть 100 очков, но это не значит, что они имеют один объект оценки (со значением 100).

Вот как я мог бы построить граф объекта:

Игровое устройство:

  • атрибут title (например, "Монополия" )
  • отношения игроков, один-ко-многим (одна игра, много игроков).

Объект проигрывателя:

  • атрибут имени (например, Джо Смит)
  • игровые отношения, один-ко-многим (один игрок, много игр)
  • оценивает отношения, один-ко-многим (один игрок, множество баллов)

Объект оценки:

  • атрибут оценки, значение int (например, 100)
  • игровое отношение, один к одному (один балл, одна игра)

Ответ 3

Еще один способ подумать об этом при проектировании вашей модели:

Игра - это объект, представляющий тип игры (монополия, теннис и т.д.)

Match - фактическая "игра", которая имеет место в определенный момент времени и имеет атрибут, такой как дата/время или период. Плюс player1, player2 и т.д. Кто бы ни принимал участие. Плюс каждая команда или игрок оценивают, например. player1Score, player2Score...

Участник - или игрок.