核心数据问题 - 检查项目是否存在

时间:2012-07-20 02:37:31

标签: iphone objective-c ios cocoa core-data

我正在研究NSScreenCast的代码示例,该示例处理导入到Core Data应用程序。 (https://github.com/subdigital/nsscreencast/tree/master/012-core-data-importing-data/BeerBrowser)。我的示例大部分都在工作。我能够按下刷新按钮,它解析json并将其导入数据库。但是,每次按下刷新按钮,它都会重新添加相同的数据。我已将其追溯到以下代码。

+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]];

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId = %d", serverId]];
[fetchRequest setFetchLimit:1];

NSError *error = nil;
NSArray *results = [moc executeFetchRequest:fetchRequest error:&error];
NSLog(@"results: %@", results);
if (error) {
    NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]);
    exit(1);
}

if ([results count] == 0) {
    return nil;
}
NSLog(@"results objectAtIndex:0 = %@", [results objectAtIndex:0]);

return [results objectAtIndex:0];
}

这种方法会发生什么,它试图查看该项目是否已存在于数据库中。如果此调用返回nil,则MasterViewController中的代码将再次添加到数据库中。我做了一些调试,serverId确实通过了。此外,fetchrequest似乎是有效的(无法调试它以确保)。正如您所看到的,我已为结果放置了一个NSLog,但它返回一个空结果。那么,如果结果计数为0,则返回nil。因此我的问题。我没有看到这个问题可能成为问题的其他地方。有什么想法吗?

Mike Riley

3 个答案:

答案 0 :(得分:4)

我刚修改了你的方法,你可以尝试一下:

+ (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc {
  NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:[Brewery entityName]];
  [fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]];
  [fetchRequest setFetchLimit:1];

  NSError *error = nil;

  // if there's no object fetched, return nil
  if ([managedObjectContext countForFetchRequest:fetchRequest error:&error] == 0) {
    NSLog(@"!!!WARN: NO Object Matches.");
    return nil;
  }

  // fetch your object
  Brewery *result = [[moc executeFetchRequest:fetchRequest error:&error] lastObject];
  if (error != nil) {
    NSLog(@"ERROR: %@ %@", [error localizedDescription], [error userInfo]);
    return nil;
  }

  NSLog(@"results objectAtIndex:0 = %@", result);
  return result;
}

注意:-countForFetchRequest:error:效率更高,因为它只返回给定获取请求返回的对象数量#39;。您可以使用此方法检查是否存在匹配的对象。

答案 1 :(得分:1)

您尝试将谓词中的标量值(NSInteger)与对象值(NSNumber)进行比较。

尝试:

[NSPredicate predicateWithFormat:@"serverId = %@", [NSNumber numberWithInteger:serverId]]

答案 2 :(得分:0)

我认为你的谓词存在问题。它应该是:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]];

你错过了双等... ....

发现它并不重要。您应该检查以确保您的moc不是零。你确定你正确传递了吗?