1

在 iPhone 上使用带有 sqlite 存储的 Core Data .... 我有一堆漫画书图像实体,每个实体都有一个包含漫画问题#的字符串,例如:image.imageTitle = @"Issue 12: Special Edition";

UI 的一部分允许用户输入问题编号以跳转到下一个问题。我的初始代码是 sloooooooow ,因为imageAtIndex:一次查询 Core Data 中的一个对象。超过数百个问题,可能需要超过 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 GuideICU regex specs之间,我认为 \b 有助于防止搜索 12 返回 120、121、122 等。相反,它根本不会从商店返回任何东西!

另一方面,如果我不使用边界一词并改为搜索stringWithFormat:@"%@",issueNumber,我会返回几十个托管对象,从 12 到 129 到 412。

在这一点上,我最好的猜测是我遇到了 Core Data 的Constraints and Limitations之一。如果没有,我做错了什么?如果是这样,是否有一种解决方法可以同时提供精确匹配单次获取的速度?

4

2 回答 2

3

\b指退格字符。尝试

[NSString stringWithFormat:@"\\b%@\\b",issueNumber];
//                           ^^   ^^

要执行 RegEx 匹配,请使用 MATCHES,而不是 CONTAINS。

于 2010-05-19T08:25:13.947 回答
1

原来边界这个词是一个红鲱鱼:我的问题是这个问题的一个变体:如果没有一些通配符来匹配我在 imageTitles 中不关心的位,正则表达式就无法成功。

因此,使用 NSPredicate 查找精确短语的一般案例解决方案是:

NSString *exactPhrase = @"phrase_you_hope_to_find_in_another_string";
NSString *regularExpression = [NSString stringWithFormat:@".*\\b%@\\b.*",exactPhrase];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"stringToSearch CONTAINS %@", exactPhrase];
// Assuming a string or an entity's string attribute named stringToSearch
于 2010-05-21T21:33:44.723 回答