我想做什么
我正在使用下面的代码将数据(历史外汇汇率)从我的后端服务器 (parse.com) 下载到我应用程序的核心数据存储。
该应用程序检查本地存储的最新可用数据,并仅从服务器获取较新的数据。如果本地还没有数据存储,它会从服务器获取所有数据。
代码的设置方式,它以 100 个对象为一组获取数据,将对象保存在 Core Data 中,获取数据现在本地存储的新的最新日期(通过使用 NSExpression
) 并获取下一批,直到服务器上不再有新对象为止 (objects.count = 0
)。
因为抓取很慢,我决定在后台线程上运行抓取和 Core Data 保存(使用 iOS 5 提供的新 Core Data 多线程模型)。
从后端服务器获取工作正常,但是......
我的问题
似乎只有那些存储在磁盘上(物理上在数据库中)的对象被 NSExpression
评估,而不是仍在内存中并将很快被保存的对象。因此,提取主要是从磁盘(内存)中检索“旧”值。
但是,当使用以下获取代码时(没有 NSExpression
和 NSDictionary
作为结果类型),我得到了当前和正确的值:
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:localEntityName];
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:YES];
request.sortDescriptors = @[sortDescriptor];
NSArray *results = [backgroundContext executeFetchRequest:request error:&error];
ForexHistory *forexHistoryItem = results.lastObject;
NSDate *lastLocalDate = forexHistoryItem.date;
NSLog(@"last local date results: %@",lastLocalDate);
我下面的代码有什么问题,它使用 NSExpression
和字典作为获取结果类型?
我的问题
如何确保查找本地最新可用日期的 NSExpression
返回最新日期?
代码
- (void)seedForexHistoryInManagedObjectContext:(NSManagedObjectContext*)context {
NSString* const localEntityName = @"ForexHistory";
NSString* const parseEntityName = localEntityName;
NSString* const parseDateIdentifier = @"date";
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath:@"date"];
NSExpression *maxPeriodExpression = [NSExpression expressionForFunction:@"max:"
arguments:@[keyPathExpression]];
NSString *expressionName = @"maxDate";
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
expressionDescription.name = expressionName;
expressionDescription.expression = maxPeriodExpression;
expressionDescription.expressionResultType = NSDateAttributeType;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:localEntityName];
request.propertiesToFetch = @[expressionDescription];
request.resultType = NSDictionaryResultType;
NSArray *currencies = @[@"AUD",@"EUR",@"NZD",@"GBP",@"BRL",@"CAD",@"CNY"];
dispatch_queue_t downloadQueue;
downloadQueue = dispatch_queue_create("download", NULL); // create serial dispatch queue
NSManagedObjectContext *moc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
moc.parentContext = context;
dispatch_async(downloadQueue,^{
[moc performBlockAndWait:^{
NSArray *objects;
do {
NSError *error;
NSArray *dateResults = [moc executeFetchRequest:request error:&error];
NSAssert(dateResults.count == 1,@"Request error!");
NSDate *lastLocalDate = dateResults.lastObject[expressionName];
NSLog(@"last local date results: %@",lastLocalDate);
PFQuery *query = [PFQuery queryWithClassName:parseEntityName];
query.limit = 100;
[query orderByAscending:parseDateIdentifier];
if (lastLocalDate) [query whereKey:parseDateIdentifier greaterThan:lastLocalDate]; // else query all
objects = [query findObjects];
[objects enumerateObjectsUsingBlock:^(PFObject *obj, NSUInteger idx, BOOL *stop) {
ForexHistory *forexHistory = [NSEntityDescription insertNewObjectForEntityForName:localEntityName
inManagedObjectContext:moc];
forexHistory.date = NULL_TO_NIL(obj[@"date"]);
[currencies enumerateObjectsUsingBlock:^(NSString *currency, NSUInteger idx, BOOL *stop) {
[forexHistory setValue:NULL_TO_NIL(obj[currency]) forKey:currency.lowercaseString];
}];
}];
NSError *saveError = nil;
[moc save:&saveError];
if (!saveError) NSLog(@"%lu forex rates saved successfully.",(unsigned long)objects.count);
else NSLog(@"Error when downloading historic forex rates: %@",error.localizedDescription);
} while (objects.count > 0);
}];
}
感谢您的帮助!
最佳答案
不幸的是,这是不可能的。请参阅 setIncludesPendingChanges:
的文档:
Special Considerations
A value of
YES
is not supported in conjunction with the result typeNSDictionaryResultType
, including calculation of aggregate results (such asmax
andmin
). For dictionaries, the array returned from the fetch reflects the current state in the persistent store, and does not take into account any pending changes, insertions, or deletions in the context.
关于ios - 基于 NSExpression 的核心数据提取不检索当前值(iOS 5、GCD),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14010809/