我正在研究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
答案 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
不是零。你确定你正确传递了吗?