2

我有这段代码:

- (void) fetchRecordsStaringFrom:(double)start limit:(double)limit whereFields:(NSArray*)whereFields haveValues:(NSArray*)whereValues sortBy:(NSString*)sortField ascending:(BOOL)isascending delegateEvent:(BOOL)delegateEvent{
NSFetchRequest *_fetchRequest = [[NSFetchRequest alloc] init];
[_fetchRequest setEntity:self.entityDescription];
// Create the sort descriptors array.
// Default sort is ID
if (sortField == NULL) {
    sortField = @"id";
}
NSSortDescriptor *authorDescriptor = [[NSSortDescriptor alloc] initWithKey:sortField ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:authorDescriptor, nil];
[_fetchRequest setSortDescriptors:sortDescriptors];
if (whereFields != Nil && whereValues != Nil && ([whereFields count] == [whereValues count])) {
    NSMutableString *predicateString = [[NSMutableString alloc] initWithString:@""];
    for (int index = 0; index < [whereFields count]; index++) {
        [predicateString appendFormat:@"%@==%@", whereFields[index], whereValues[index]];
        if (index < [whereFields count] - 1) {
            [predicateString appendString:@" AND "];
        }
    }
    // Delete old cache to make sure always get new data
    [NSFetchedResultsController deleteCacheWithName:nil];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:predicateString];
    [_fetchRequest setPredicate:predicate];
} else {
}
self.fetchRequest = _fetchRequest;
self.fetchResultController = [[NSFetchedResultsController alloc] initWithFetchRequest:self.fetchRequest managedObjectContext:self.context sectionNameKeyPath:nil cacheName:nil];
self.fetchResultController.delegate = self;
NSError *_error;
if (delegateEvent) {
    if ([self.delegate respondsToSelector:@selector(CoreDataEntityRequestStartEvent:::)]) {
        [self.delegate CoreDataEntityRequestStartEvent:self :self.fetchRequest :self.fetchResultController];
    }
    if (![self.fetchResultController performFetch:&_error]) {
        if ([self.delegate respondsToSelector:@selector(CoreDataEntityRequestErrorEvent::)]) {
            [self.delegate CoreDataEntityRequestErrorEvent:self :_error];
        }
    } else {
        if ([self.delegate respondsToSelector:@selector(CoreDataEntityRequestSuccessEvent:::)]) {
            [self.delegate CoreDataEntityRequestSuccessEvent:self :self.fetchRequest :self.fetchResultController];
        }
    }
    if ([self.delegate respondsToSelector:@selector(CoreDataEntityRequestEndEvent:::)]) {
        [self.delegate CoreDataEntityRequestEndEvent:self :self.fetchRequest :self.fetchResultController];
    }
} else {
    [self.fetchResultController performFetch:&_error];
}
}

执行时,上面的方法将从 SQLITE 数据库中获取数据,这里没有问题,但是当我使用外部 SQLITE 编辑器或通过其他方式更改 SQLITE,然后使用相同的参数再次执行时,它无法获取新数据并保持旧数据数据,除非我重新启动应用程序。

我到处寻找,可能是因为缓存,但正如您所见,我已经清除了缓存,但仍然无法获取新数据。


感谢您的回复,答案是:仅供测试,

这是实际情况:例如,在屏幕UITableView中,从互联网获取数据(数据不完整),将其存储在数据库中然后加载并显示在视图中,然后当点击一个单元格时,将从互联网获取完整数据以供选择单元格,更新数据库,并将其显示在其他屏幕上。当返回 UItableView 并从数据库重新加载时,由于之前的更新,记录集应该被更改,所以当用户在同一个单元格上重新点击时,不需要从互联网获取数据,因为我们已经完成了选定单元格的数据。但是....正如我在上面的问题中所解释的,NSFetchResultController 没有提供新数据,即使在 SQLITE 文件更新之后!

4

2 回答 2

3

好的,对不起,长时间的休息,这就是我为将来遇到此问题的任何人解决问题的方法,所有学分都归功于这里的每个人,谢谢。

执行获取请求时,请确保删除旧缓存

[NSFetchedResultsController deleteCacheWithName:nil];

然后对于 fetchResultController 中所有获取的对象,使用选项 mergeChanges YES 调用 refreshObject

for (int i = 0; i < [[self.fetchResultController fetchedObjects] count]; i++) {
[self.context refreshObject:[[self.fetchResultController fetchedObjects] objectAtIndex:i] mergeChanges:YES];
}

这将确保您每次执行获取请求时都能获取新数据

于 2013-10-30T06:45:45.677 回答
1

Core Data 跟踪内存中的实体对象,但延迟加载实际的属性值。延迟加载的行为称为故障。如果您直接在存储中修改属性值,然后为相应的托管对象触发错误,则更改的值将加载到内存中。然后,托管对象将保留在内存中,直到不再需要为止。Core Data 假设它拥有对存储的控制权,并且不会尝试再次加载托管对象的属性值,直到对象无效并为其触发另一个故障。因此,如果您在已为记录填充托管对象后更改值,则更改不会立即出现。您需要了解托管对象的行为和生命周期,才能确定何时期望更改在内存中表示。

还要注意不要在应用程序运行时直接对商店进行更改,然后以将更改提交到数据库的方式与应用程序交互。如果 Core Data 需要更新您已修改的记录,它将假定(在正常情况下正确地如此)它具有独占控制权,并会用来自内存管理对象的数据覆盖您偷偷摸摸的更改。

于 2013-09-16T05:29:36.927 回答