我终于至少缩小了这个问题的范围。我正在计算一些支出的聚合函数(如本例中的总和)。如果我更改了一些支出,则此聚合获取不会立即刷新,而是会在一段时间后刷新(可能是在将更改保存到数据库之后)。我在文档中找到了这部分:
- (void)setIncludesPendingChanges:(BOOL)yesNo
根据文档
YES
不支持与结果类型一起使用的 值NSDictionaryResultType
,包括聚合结果的计算(例如最大值和最小值)。对于字典,从 fetch 返回的数组反映了持久存储中的当前状态,并且不考虑上下文中的任何未决更改、插入或删除。如果您需要为一些简单的聚合(例如 max 和 min)考虑挂起的更改,则可以改用普通的 fetch 请求,按您想要的属性排序,获取限制为 1。
好的,我如何仍然包含待处理的更改?我正在使用 aNSFetchedResultsController
来显示我的数据。这是我的聚合函数:
- (NSNumber *)getExpendituresAmountForCostPeriod:(CostPeriod)costPeriod
{
NSLog(@"getExpenditures_Start");
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Expenditures"];
[fetchRequest setResultType:NSDictionaryResultType];
NSDate *startDate = [NSDate startDateForCostPeriod:[self getBiggestCostPeriod]];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"forSpendingCategory = %@ AND date >= %@", self, startDate];
//Define what we want
NSExpression *keyPathExpression = [NSExpression expressionForKeyPath: @"amount"];
NSExpression *sumExpression = [NSExpression expressionForFunction: @"sum:"
arguments: [NSArray arrayWithObject:keyPathExpression]];
//Defining the result type (name etc.)
NSExpressionDescription *expressionDescription = [[NSExpressionDescription alloc] init];
[expressionDescription setName: @"totalExpenditures"];
[expressionDescription setExpression: sumExpression];
[expressionDescription setExpressionResultType: NSDoubleAttributeType];
// Set the request's properties to fetch just the property represented by the expressions.
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObject:expressionDescription]];
NSLog(@"%@", self.managedObjectContext);
// Execute the fetch.
NSError *error = nil;
NSArray *objects = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
if (objects == nil) {
return [NSNumber numberWithDouble:0];
} else {
if ([objects count] > 0) {
return [[objects objectAtIndex:0] valueForKey:@"totalExpenditures"];
} else {
return [NSNumber numberWithDouble:0];
}
}
}
编辑:
*循环是否NSSet
可能且足够快?*
- (NSNumber *)getExpendituresAmountForCostPeriod:(CostPeriod)costPeriod
{
NSDate *startDate = [NSDate startDateForCostPeriod:[self getBiggestCostPeriod]];
double total = 0;
for(Expenditures *expenditure in self.hasExpenditures){
if(expenditure.date >= startDate){
total = total + [expenditure.amount doubleValue];
}
}
return [NSNumber numberWithDouble:total];
}
编辑最后回答 谢谢大家,我终于在循环中找到了问题。这工作得非常快而且很好:
- (NSNumber *)getExpendituresAmountForCostPeriod:(CostPeriod)costPeriod
{
NSDate *startDate = [NSDate startDateForCostPeriod:[self getBiggestCostPeriod]];
double total = 0;
for(Expenditures *expenditure in self.hasExpenditures){
if([expenditure.date compare: startDate] == NSOrderedDescending){
total = total + [expenditure.amount doubleValue];
}
}
return [NSNumber numberWithDouble:total];
}
从控制器DidChangeContent 调用。
今天就够了.. :-)