Как я могу получить доступ к данным в отношениях один ко многим? - PullRequest
3 голосов
/ 21 февраля 2011

Я купил свою первую книгу с инструкциями по программированию только 2 месяца назад, так что я знаю, что она, вероятно, довольно проста, но я пытаюсь научиться использовать Core Data, и я не могу понять, как извлечь данные из объекта в отношениях один ко многим. Я провел весь день, гугляя и читая документы Apple, но не могу найти действительно простого объяснения.

Я настроил свою базовую модель данных со следующими объектами:

«Поездка» имеет отношение «один ко многим» от «контрольных списков» до…

«Контрольный список» имеет отношение «один ко многим» от «checklistItems» до…

"ChecklistItem".

Затем в моем делегате приложения в applicationDidFinishLaunching: я добавил следующий простой код, который просто создает некоторые управляемые объекты и затем отображает их в консоли:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.

    // TEST CORE DATA - MAKE OBJECTS
    NSManagedObjectContext *context = [self managedObjectContext];
    NSManagedObject *trip = [NSEntityDescription insertNewObjectForEntityForName:@"Trip" inManagedObjectContext:context];
    [trip setValue:@"Test Trip" forKey:@"tripName"];

    NSManagedObject *checklist = [NSEntityDescription insertNewObjectForEntityForName:@"Checklist" inManagedObjectContext:context];
    [checklist setValue:@"Test Checklist" forKey:@"checklistName"];


    NSManagedObject *checklistItem = [NSEntityDescription insertNewObjectForEntityForName:@"ChecklistItem" inManagedObjectContext:context];
    [checklistItem setValue:@"Test Checklist Item" forKey:@"checklistItemName"];
    [checklistItem setValue:[NSNumber numberWithBool:TRUE] forKey:@"checklistItemChecked"];
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }

    // TEST CORE DATA - LIST OBJECTS
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Trip" inManagedObjectContext:context]];

    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (NSManagedObject *info in fetchedObjects) {
        NSLog(@"Trip Name: %@", [info valueForKey:@"tripName"]);

        NSManagedObject *aChecklist = [info valueForKey:@"checklists"];
        NSLog(@"Checklist Name: %@", [aChecklist valueForKey:@"checklistName"]);

        NSManagedObject *aChecklistItem = [aChecklist valueForKey:@"checklistItems"];
        NSLog(@"Checklist Item Name: %@", [aChecklistItem valueForKey:@"checklistItemName"]);
        NSLog(@"Checklist Item Checked: %@", [aChecklistItem valueForKey:@"checklistItemChecked"] ? @"Yes it is!" : @"No It's Not!");
    }
    [fetchRequest release];

    [self.window makeKeyAndVisible];

    return YES;
}

Когда я запускаю программу, я получаю в терминале следующее:

2011-02-21 18: 01: 14.144 BYG [38204: 207] Название поездки: Тестовая поездка 2011-02-21 18: 01: 14.146 BYG [38204: 207] Имя контрольного списка: {( )} 2011-02-21 18: 01: 14.147 BYG [38204: 207] Контрольный список Имя элемента: {( )} 2011-02-21 18: 01: 14.147 BYG [38204: 207] Пункт проверки Проверен: Да, это так!

Два элемента (Имя контрольного списка и Имя элемента контрольного списка) просто возвращают пустые скобки. Я думаю, что у меня есть туманное понимание того, почему это так: эти два атрибута находятся во многих отношениях, поэтому он не знает , какое имя контрольного списка он намеревался сказать. Как мне получить значения для этих объектов?

Извините, если это объяснение туманно. Мой мозг в значительной степени отключился после дня, когда я пытался разобраться:)

-------------------------- EDIT ------

Спасибо за помощь! Я изменил свой код, и он, кажется, работает! Буду признателен, если вы скажете мне, все ли хорошо выглядит, или я делаю какие-то ошибки новичка:

   - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    // Override point for customization after application launch.   
    // TEST CORE DATA - MAKE OBJECTS
    NSManagedObjectContext *context = [self managedObjectContext];

    Trip *newTrip = [Trip addEntityForContext:context];
    newTrip.tripName = @"Test Trip with addEntity"; 

    Checklist *newChecklist = [NSEntityDescription insertNewObjectForEntityForName:@"Checklist" inManagedObjectContext:context];
    [newTrip addChecklistsObject:newChecklist];
    newChecklist.checklistName = @"Test Checklist"; 

    ChecklistItem *newChecklistItem = [NSEntityDescription insertNewObjectForEntityForName:@"ChecklistItem" inManagedObjectContext:context];
    [newChecklist addChecklistItemsObject:newChecklistItem];
    newChecklistItem.checklistItemName = @"Test Checklist Item";
    newChecklistItem.checklistItemChecked = [NSNumber numberWithBool:TRUE];

    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }

    // TEST CORE DATA - LIST OBJECTS
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    [fetchRequest setEntity:[NSEntityDescription entityForName:@"Trip" inManagedObjectContext:context]];    
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    for (Trip *info in fetchedObjects) {
        NSLog(@"Trip Name: %@", info.tripName);

        NSSet *aChecklistSet = [[NSSet alloc]initWithSet:info.checklists];
        Checklist *aChecklist = [aChecklistSet anyObject];
        NSLog(@"Checklist Name: %@", aChecklist.checklistName);

        NSSet *aChecklistItemSet = [[NSSet alloc]initWithSet:aChecklist.checklistItems];
        ChecklistItem *aChecklistItem = [aChecklistItemSet anyObject];
        NSLog(@"Checklist Item Name: %@", aChecklistItem.checklistItemName);
        NSLog(@"Checklist Item Checked: %@", aChecklistItem.checklistItemChecked ? @"Yes it is!" : @"No It's Not!");
    }
    [fetchRequest release];

    [self.window makeKeyAndVisible];

    return YES;
}

(я еще не реализовал addEntity, так как я не был уверен, как объекты модели могли бы получить контекст, но я думаю, что это всего лишь элемент кода, поэтому я пока не беспокоюсь об этом).

1 Ответ

2 голосов
/ 22 февраля 2011

Вы делаете это тяжело для себя.Вы должны сделать (модель) класс.Если вы не знаете модель, смотрите:MVC

Вы можете сделать это, чтобы перейти к вашей coredatamodel, нажать на модель (не на Entity) и выбрать новый в меню файла.Здесь вы можете выбрать создание подклассов NSManagedObject.Это создаст классы для выбранных вами объектов.

Эти классы представляют ваши основные объекты данных.

Попробуйте реализовать статические методы во всех классах, например:

+ (CheckListItem *) addEntity {
   return (CheckListItem *)[NSEntityDescription insertNewObjectForEntityForName:@"ChecklistItem" inManagedObjectContext:context];
}

ДляВ контексте вы можете сделать две вещи.1) Установите контекст из вашего приложения: didFinishLaunchingWithOptions: 2) Сделайте единственный экземпляр для хранения вашего контекста.(Лучшее решение)

Теперь вы можете легко позвонить из приложения, которое завершило запуск:

CheckListItem *newItem = [CheckListItem addEntity];
CheckList *newList = [CheckList addEntity];

newItem.name = @"MyCheckListItemName";
newList.name = @"MyListName";

Для отношения, которое вы можете сделать:

newItem.checkList = newList;

Или:

[newList addCheckListItemsObject:newItem];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...