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

Iphone 核心数据问题-检查项目是否存在,iphone,objective-c,ios,cocoa,core-data,Iphone,Objective C,Ios,Cocoa,Core Data,我正在处理NSScreenCast中的一个代码示例,该示例处理导入到核心数据应用程序()。我的例子在很大程度上起了作用。我可以按下刷新按钮,它解析json并将其导入数据库。但是,每次我按下刷新按钮,它都会重新添加相同的数据。我将其追溯到以下代码 + (Brewery *)breweryWithServerId:(NSInteger)serverId usingManagedObjectContext:(NSManagedObjectContext *)moc { NSFetchRequest *

我正在处理NSScreenCast中的一个代码示例,该示例处理导入到核心数据应用程序()。我的例子在很大程度上起了作用。我可以按下刷新按钮,它解析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中的代码会再次将其添加到数据库中。我已经做了一些调试,服务器ID确实通过了。另外,fetchrequest似乎是有效的(还不能确定是否调试它)。正如您所看到的,我为结果放置了一个NSLog,但它返回一个空结果。因此,如果结果计数为0,则返回nil。这就是我的问题。我不认为这个问题在其他任何地方会成为问题。有什么想法吗


Mike Riley

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

+ (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:
更有效,因为它只“返回给定提取请求将返回的对象数”。您可以使用此方法检查是否存在匹配的对象。

我认为您的谓词中存在问题。应改为:

[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"serverId == %d", serverId]];
你错过了双等分


发现这不重要。您应该检查以确保您的
moc
不是零。是否确实正确传递了它?

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

尝试:


谢谢你的帮助。我试过了,但还是遇到了同样的问题。在深入研究它之后,似乎它所比较的serverId在任何时候都没有保存到数据库中。因此,setPredicate正在比较传递给没有数据的列的serverId。因此,它与任何东西都不匹配。我正在查看代码,看看是否能找到它。数据模型确实显示了服务器ID。@MikeRiley'NSLog(@“results:%@”,results);'&'的日志是什么NSLog(@“结果对象索引:0=%@,[results对象索引:0]);”?实际上,不是这样的-
=
=
NSPredicate
中是一样的。查看这里的基本比较部分,感谢您指出这一点。我总是用双等分。医生不会撒谎。
[NSPredicate predicateWithFormat:@"serverId = %@", [NSNumber numberWithInteger:serverId]]