iPhone で sqlite ストアを使用してコア データを使用する....コミックの issue# を含む文字列を持つコミック ブックのイメージ エンティティがたくさんあります。たとえば、次のようになります。image.imageTitle = @"Issue 12: Special Edition";
UI の一部では、ユーザーは問題番号を入力して次の問題にジャンプできます。このための私の最初のコードは sloooooooow でした。これは、imageAtIndex:
Core Data に対して一度に 1 つのオブジェクトを照会するためです。数百の問題を超えると、最初のループを通過するだけで 40 秒以上かかる場合があります。
スローコード:
// Seek forward from the next page to the right
for (i = currentPage + 1; i < [self numberOfPages]; i++) {
iterationString = [[self imageAtIndex:i] imageTitle];
iterationNumber = [[iterationString stringByTrimmingCharactersInSet:nonDigits] intValue];
if (issueNumber == iterationNumber) {
keepLooking = NO;
break;
}
}
// If nothing was found to the right, seek forward from 0 to the current page
if (i == [self numberOfPages] && keepLooking) {
for (i = 0 ; i < currentPage; i++) {
iterationString = [[self imageAtIndex:i] imageTitle];
iterationNumber = [[iterationString stringByTrimmingCharactersInSet:nonDigits] intValue];
if (issueNumber == iterationNumber) {
keepLooking = NO;
break;
}
}
}
より効率的なソリューションを期待して、次のように Core Data に対して直接クエリを実行することにしました。
NSString *issueNumber = @"12";
NSString *issueWithWordBoundaries = [NSString stringWithFormat:@"\\b%@\\b",issueNumber];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(groupID == %@) AND (imageTitle CONTAINS %@)", groupID, issueWithWordBoundaries];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CBImage" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setPredicate:predicate];
[fetchRequest setIncludesSubentities:NO]; // Not sure if this is needed, but just in case....
// Execute the fetch
NSError *error = nil;
NSArray *fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:&error];
// [fetchedImages count] == 0
Predicate Programming GuideとICU regex specsの間で、\b が 12 の検索で 120、121、122 などを返すのを防ぐのに役立つと考えました。代わりに、ストアからは何も返されません!
一方、単語の境界を省略して代わりに を検索するとstringWithFormat:@"%@",issueNumber
、12 から 129 から 412 まで、多数の管理対象オブジェクトが返されます。
この時点で、Core Data のConstraints and Limitationsの 1 つに遭遇したと推測できます。そうでない場合、私は何を間違っていますか? もしそうなら、完全一致と単一フェッチの速度の両方を提供する回避策はありますか?