【问题标题】:Core Data issue - checking if item exists核心数据问题 - 检查项目是否存在
【发布时间】:2012-07-19 07:14:57
【问题描述】:

我正在编写来自 NSScreenCast 的代码示例,该示例处理导入到 Core Data 应用程序 (link)。我有大部分工作的例子。我可以按下刷新按钮,它解析 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。因此我的问题。我没有看到这个问题可能成为问题的任何其他地方。有什么想法吗?

迈克·莱利

【问题讨论】:

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


    【解决方案1】:

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

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

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

    发现没关系。您应该检查以确保您的 moc 不为零。你确定你正确地传递它吗?

    【讨论】:

    【解决方案2】:

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

    试试:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 感谢您的帮助。我试过了,仍然遇到同样的问题。在深入研究它之后,似乎它与之比较的 serverId 在任何时候都没有保存到数据库中。因此 setPredicate 正在比较传递给没有数据的列的 serverId。因此它永远不会匹配任何东西。我现在正在查看代码,看看是否可以找到它。数据模型确实显示了 serverId。
      • @MikeRiley 'NSLog(@"results: %@", results);' 的日志是什么& 'NSLog(@"results objectAtIndex:0 = %@", [results objectAtIndex:0]);'?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-11-11
      • 1970-01-01
      • 2011-10-05
      • 1970-01-01
      • 2021-10-17
      • 1970-01-01
      • 2012-02-12
      相关资源
      最近更新 更多