从NSFetchRequest返回的数组计数是错误的

时间:2014-01-02 08:01:08

标签: ios objective-c core-data nsfetchrequest

我正在使用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) { … }

2 个答案:

答案 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;
     }
}