2013-09-01 2 views
5

У меня есть NSManagedObject со связанными объектами. Отношение описывается keyPath.NSFetchedResultsController, который содержит объекты из отношения

Теперь я хочу отобразить эти связанные объекты в виде таблицы. Конечно, я мог бы просто взять NSSet с этими объектами в качестве источника данных, но я бы предпочел восстановить объекты с помощью NSFetchedResultsController, чтобы воспользоваться его функциями.

Как создать предикат, который описывает эти объекты?

+0

Опишите сущности и отношения и что именно вы хотите отобразить. –

+0

Это не имеет значения. Я рассматриваю общее решение, основанное на объекте и пути ключа отношения. –

ответ

13

Чтобы отобразить связанные объекты данного объекта с выбранным контроллером результатов, , вы должны использовать обратное отношение в предикате. Например:

enter image description here

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

Parent *theParent = ...; 
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Child"]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"parent = %@", theParent]; 
[request setPredicate:predicate]; 

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

enter image description here

Для отображения улиц данной страны:

Country *theCountry = ...; 
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Street"]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = %@", theCountry]; 
[request setPredicate:predicate]; 
+0

Как именно получить обратное отношение, особенно если у меня есть ключевой путь с несколькими элементами? –

+0

@de .: См. Обновленный ответ. –

+0

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

1

Благодаря Мартин, вы дали мне важную информацию.

родового получить ключ пути я нашел следующую реализацию:

// assume to have a valid key path and object 
    NSString *keyPath; 
    NSManagedObject *myObject; 

    NSArray *keys = [keyPath componentsSeparatedByString:@"."]; 
    NSEntityDescription *entity = myObject.entity; 
    NSMutableArray *inverseKeys = [NSMutableArray arrayWithCapacity:keys.count]; 
    // for the predicate we will need to know if we're dealing with a to-many-relation 
    BOOL isToMany = NO; 
    for (NSString *key in keys) { 
     NSRelationshipDescription *inverseRelation = [[[entity relationshipsByName] valueForKey:key] inverseRelationship]; 
     // to-many on multiple hops is not supported. 
     if (isToMany) { 
      NSLog(@"ERROR: Cannot create a valid inverse relation for: %@. Hint: to-many on multiple hops is not supported.", keyPath); 
      return nil; 
     } 
     isToMany = inverseRelation.isToMany; 
     NSString *inverseKey = [inverseRelation name]; 
     [inverseKeys insertObject:inverseKey atIndex:0]; 
    } 
    NSString *inverseKeyPath = [inverseKeys componentsJoinedByString:@"."]; 
    // now I can construct the predicate 
    if (isToMany) { 
     predicate = [NSPredicate predicateWithFormat:@"ANY %K = %@", inverseKeyPath, self.dataObject]; 
    } 
    else { 
     predicate = [NSPredicate predicateWithFormat:@"%K = %@", inverseKeyPath, self.dataObject]; 
    } 

Update: Я изменил формат предикат, так что он также поддерживает многие-ко-многим отношений.

Обновление 2 Это становится все сложнее: мне нужно проверить мое обратное отношение, если оно для многих, и использовать разные предикаты. Я обновил приведенный выше пример кода.

-2
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = '%@'", theCountry]; 

Вы пропустите '' в предикат с строкой Формата. Теперь это работает.

+0

Неправильное использование. С кавычками ''% @ ''% @ is * нераскрывается * аргументом. –

+0

это не сработало для меня –

Смежные вопросы