0

私はモデルを持っています:

Place:
title
address
category <--->> Category:
                title

また、カテゴリ名としてセクションを含むテーブル ビューが必要ですが、場所のタイトルに基づいて検索できるようにしたいと考えています。では、指定された searchText に一致するカテゴリとタイトルのみを持つテーブル ビューのデータ セットを取得する最善の方法は何でしょうか? 現在、結果を NSDictionary に入れていますが、あまり効率的ではないようです。特に削除タイプの操作を実行する場合、多くの問題に遭遇します。現在、私は次のことを行っていますが、むしろ直接 FetchedResultsController を返します。

+ (NSMutableDictionary *)getDictionaryResultsInContext: (NSManagedObjectContext *)context
                                         forSearchText: (NSString *)searchText {

    NSFetchRequest *req = [NSFetchRequest fetchRequestWithEntityName:@"Place"];
    if(![searchText isEqualToString:@""] && searchText != nil){
        req.predicate = [NSPredicate predicateWithFormat:@"(category.name CONTAINS[cd] %@) OR (placeTitle CONTAINS[cd] %@) OR (details CONTAINS[cd] %@)", searchText, searchText, searchText];
        NSLog(@"ModelHelper.getResults: Search text given, creating predicate: %@", req.predicate);
    }
    req.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"placeTitle"
                                                                                 ascending:YES
                                                                                  selector:@selector(localizedCaseInsensitiveCompare:)]];
    NSFetchedResultsController *controller = [[NSFetchedResultsController alloc]initWithFetchRequest:req
                                                                                managedObjectContext:context
                                                                                  sectionNameKeyPath:nil
                                                                                           cacheName:nil];
    NSError *error = nil;
    [controller performFetch:&error];
    if (error) {
        NSLog(@"- Model Search ERROR: %@ (%@)", [error localizedDescription], [error localizedFailureReason]);
    }

    NSLog(@"- Got results: %i", [controller.fetchedObjects count]);

    NSMutableDictionary* ret = [[NSMutableDictionary alloc]init];

    for(Place* obj in controller.fetchedObjects){
        if(obj != nil){
            NSManagedObjectID* categoryId = obj.category.objectID;
            if(categoryId != nil){
                NSMutableArray* ary = (NSMutableArray*)[ret objectForKey:categoryId];
                if(ary == NULL){
                    ary = [[NSMutableArray alloc]init];
                    [ret setObject:ary forKey:categoryId];
                }
                [ary addObject:obj];
            }
            else {
                // Shouldnt happen
                NSLog(@"- Category was nil.");
            }
        }
        else {
            // Shouldnt happen
            NSLog(@"- Place was nil.");
        }
    }

    return(ret);
}
4

1 に答える 1

0

あなたのデータモデルは意味がありません。あなたは本当に多対多の関係を望んでいます。

カテゴリは、複数の場所を含めることができる場合にのみ意味があります。したがって、category->place関係は対多でなければなりません。必要に応じて、1 つの場所を複数のカテゴリに含めることができますplace->category。そうでない場合は、1 対 1 の関係にする必要があります。

だからどちらか

Place <<----------> Category

また

Place <<--------->> Category

あなたの質問のバージョンではありません。あなたのシナリオでは、レストランである場所は「レストラン」というタイトルのカテゴリを取得し、レストランである次の場所については、「レストラン」というタイトルの新しいカテゴリを作成する必要があります。意味を成さない。

単純なケース (1 対多) では、述語は次のようになります。

[NSPredicate predicateWithFormat:
  @"title CONTAINS[cd] %@ OR address CONTAINS[cd] %@", searchTerm, searchTerm];

より複雑なケース (多対多) では、場所が複数のセクションにリストされる可能性があるという問題があります。したがって、カテゴリをフェッチし、カテゴリの数を各セクションの行数として使用し、次の述語でフィルタリングする必要があります。

[NSPredicate predicateWithFormat:
  @"ANY places.title CONTAINS[cd] %@ OR ANY places.address CONTAINS[cd] %@",
  searchTerm, searchTerm]; 
于 2013-04-22T14:52:43.383 に答える