我正在使用Core Data来缓存数据,这是我插入对象的代码:
//data array count is 15
for (NSDictionary *dictionary in dataArray)
{
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CacheData" inManagedObjectContext:context];
[request setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title LIKE '%@'",dictionary[@"title"]];
[request setPredicate:predicate];
NSArray *fetchArray = [context executeFetchRequest:request error:NULL];
if ([fetchArray count] == 0)
{
CacheData *cacheData = [NSEntityDescription insertNewObjectForEntityForName:@"CacheData" inManagedObjectContext:context];
[cacheData setTitle:dictionary[@"title"]];
[cacheData setLink:dictionary[@"link"]];
[cacheData setPublishDate:dictionary[@"pubDate"]];
NSError *insertError = nil;
if (![context save:&insertError])
{
return NO;
}
}
}
dataArray
的计数是15,所以我应该向Core Data插入15个项目。
但是,一旦我使用NSFetchRequest
来获取项目,返回的数组计数加1,并且变为16,再次获取项目,它再次添加1到17:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"CacheData" inManagedObjectContext:[[CacheDataManagement sharedInstance] managedObjectContext]];
[request setEntity:entity];
NSArray *fetchArray = [[[CacheDataManagement sharedInstance] managedObjectContext] executeFetchRequest:request error:NULL];
for (CacheData *data in fetchArray) {
NSLog(@"fetch:%@",[data title]);
}
NSLog(@"%ld",[fetchArray count]); //fetch array count is 16
我的代码出了什么问题?
更新
将if ([fetchArray count] != 0) { … }
更改为if ([fetchArray count] == 0) { … }
答案 0 :(得分:1)
由于这个问题对我来说不太清楚(我想了解更多细节),我会尝试给你一些提示。
首先,save
应该在for
循环之外完成(此外,在return
内进行// for in loop here
NSError *insertError = nil;
if (![context save:&insertError]) {
NSLog("%@", insertError);
return NO; // do it if the method you are running in returns a bool
}
是不正确的。)
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"title == %@",dictionary[@"title"]];
其次,要检查是否重复,您应该依赖GUID,但如果没有,则谓词应如下所示。
executeFetchRequest:error:
第三,countForFetchRequest:error:
的执行也应该替换为for
,因为您不需要返回对象而只需要返回计数。根据Apple doc,它
返回给定获取请求所具有的对象数 如果它已传递给executeFetchRequest,则返回:error:。
最后,在{{1}}循环中,您每次都在执行请求。我的建议是在循环之前移动执行请求,然后检查其中的结果。根据{{3}}。在这种情况下,模式将强制您为您的实体设置GUID。
显然,这些只是提示。找到问题的真正方法是调试。此外,我将从新环境开始执行测试,即应用程序已从模拟器或设备中删除。
答案 1 :(得分:0)
在您的代码[fetchArray count] != 0
中检查插入数据是否已存在。尝试更改它
if ([fetchArray count] == 0)
{
CacheData *cacheData = [NSEntityDescription insertNewObjectForEntityForName:@"CacheData" inManagedObjectContext:context];
[cacheData setTitle:dictionary[@"title"]];
[cacheData setLink:dictionary[@"link"]];
[cacheData setPublishDate:dictionary[@"pubDate"]];
NSError *insertError = nil;
if (![context save:&insertError])
{
return NO;
}
}