Сбой основных данных iPhone

#iphone #ios #ipad #core-data

#iPhone #iOS #iPad #основные данные

Вопрос:

У меня есть две сущности: продукты и пакеты. У каждого есть свой класс. Продукт может состоять из нескольких пакетов.

Сущности определяются следующим образом:

 PRODUCTS
name, string
number, integer 16
fromBundle = to-many relationship to product

BUNDLE
name, string
number, integer 16
product = to-many relationship to fromBundle
 

Продукты были распределены по пакетам следующим образом:

 // suppose bundle 1 is composed of products 1, 2, 3 and 4.
NSArray *myProd = [NSArray arrayWithObjects:
    [NSNumber numberWithInt:1],
    [NSNumber numberWithInt:2],
    [NSNumber numberWithInt:3],
    [NSNumber numberWithInt:4],
    nil];

int bundleNumber = 1;
NSString *bundleName = @"My Bundle";
Bundle *aBundle = nil;

NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];

request.entity = [NSEntityDescription entityForName:@"Bundle" inManagedObjectContext:context];
request.predicate = [NSPredicate predicateWithFormat: @"(number == %d)", bundleNumber];
NSError *error = nil;
aBundle = [[context executeFetchRequest:request error:amp;error] lastObject];

// as the bundle does not exist, this will run
if (!error amp;amp; !aBundle) {
    aBundle = [NSEntityDescription insertNewObjectForEntityForName:@"Bundle" inManagedObjectContext:context];
    aBundle.string = bundleName;
    aBundle.Number = [NSNumber numberWithInt:bundleNumber];

    for (NSNumber *umNum in myProd) {

            // the product with number = aNum is retrieved... yes it is valid at this point 
            Product *oneProduct = [ProductWithNumber:umNum inManagedObjectContext:context];
            NSMutableSet *mutableSet = [oneProduct mutableSetValueForKey:@"fromBundle"];
            [mutableSet addObject:aBundle];
    }
// Save the context.
NSError *error = nil;
if (![context save:amp;error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}

// everything is fine at this point.
 

Теперь я хочу получить список всех продуктов, которые принадлежат к определенному пакету…

Чтобы сделать это, я использую этот метод в классе Bundle

   (NSArray *)ProductsInBundle:(Bundle*)aBundle inManagedObjectContext:(NSManagedObjectContext *)context
{
    NSArray *all = nil;


    NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];
    request.entity = [NSEntityDescription entityForName:@"Products" inManagedObjectContext:context];
    request.predicate = [NSPredicate predicateWithFormat:@"(fromBundle == %@)", aBundle];

    NSError *error = nil;
    all = [context executeFetchRequest:request error:amp;error]; // crashes here

    return all;
}
 

он выходит из строя в назначенной строке последнего метода с сообщением «ключ to-many здесь не разрешен», когда я пытаюсь это сделать

 NSArray *allProductsInBundle = [Bundle ProductsInBundle:aBundle inManagedObjectContext:self.managedObjectContext];
 

На данный момент aBundle действителен.

Комментарии:

1. Является ли ‘Tabuleiros’ здесь просто ошибкой копирования / вставки для вашего вопроса здесь? РЕДАКТИРОВАТЬ: похоже, вы уже исправили это ^ _ ^

2. Как вы создаете класс Bundle? (т. Е. Фактический заголовок и реализацию класса, у вас есть Core Data, которые генерируют это для вас?)

Ответ №1:

Я думаю, что ваш предикат неверен. У вас есть не свойство bundle, а свойство fromBundle.

Если это действительно fromBundle, то ваш предикат должен быть:

 equest.predicate = [NSPredicate predicateWithFormat:@"(fromBundle == %@)", aBundle];
 

Редактировать:

Если вы пытаетесь выполнять операции со многими отношениями, вам нужно будет использовать агрегированные функции для предиката. Я думаю, что в вашем случае вам понадобится IN операция.

http://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-215891

Комментарии:

1. извините за это, это была опечатка, так как мне пришлось изменить код, чтобы опубликовать его здесь, чтобы сделать его более понятным. Я исправил это.

Ответ №2:

Почему вы делаете выборку, когда у вас есть отношения? Это тяжело и дорого. Просто запросите продукты для пакета через

 [aBundle valueForKey:@"product"];
 

Выборка не нужна и вызывает попадание на диск, когда он вам, вероятно, не нужен. Основные данные, скорее product всего, кэшируются.

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

 [product setValue:bundle forKey:@"fromBundle"];
 

Core Data будет управлять другой стороной отношений.