gpt4 book ai didi

objective-c - 插入的对象不会反射(reflect)在 NSFetchRequest 的查询结果中

转载 作者:行者123 更新时间:2023-11-28 19:15:23 25 4
gpt4 key购买 nike

我刚刚开始接触 iOS 开发和 Core Data 技术。

我想做的是将对象插入到核心数据中,然后在同一上下文中运行获取请求以查找新插入的对象。

这是我用来插入对象的代码:

+(Reward*) rewardForAction: (Actions) action
inManagedObjectContext: (NSManagedObjectContext *) context {

NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Reward"];
NSPredicate *actionPredicate =
[NSPredicate predicateWithFormat:@"action = %@",
[NSString stringWithFormat:@"%i", action]];

NSPredicate *todayPredicate =
[NSPredicate predicateWithFormat:@"when > %@",
[NSDate today]];

NSLog(@"Today's midnight :%@", [NSDate today]);
request.predicate =
[NSCompoundPredicate andPredicateWithSubpredicates:
[NSArray arrayWithObjects: actionPredicate, todayPredicate, nil]];

NSError *error = nil;
NSArray *matches = [context executeFetchRequest: request error: &error];

Reward *reward = nil;
if(!matches) {
NSLog(@"ERROR: failed to retrieve rewards");
} else if(matches.count > 0) {
NSLog(@"WRONG: reward already exists");
} else {
reward = [NSEntityDescription insertNewObjectForEntityForName:@"Reward"
inManagedObjectContext:context];
reward.action = [NSNumber numberWithInt:action];
reward.when = [NSDate date];
reward.pointsEarned = [Reward getPointsForAction:action];
}

[Stats track: context];

[context save:nil];

return reward;
}

此代码首先检查今天是否已经为某些操作提供了奖励,如果没有,则提供奖励。

用相同的参数调用这个方法两次,就像这样

[奖励 rewardForAction:APPLICATION_LAUNCH inManagedObjectContext: self.db.managedObjectContext];[奖励 rewardForAction:APPLICATION_LAUNCH inManagedObjectContext: self.db.managedObjectContext];

预计只会插入一个对象。

但是,实际上它向核心数据中插入了两个对象。在调试器中,当一个对象已经存在时,我看到第二个获取请求不返回任何对象。

看起来 NSFetchRequest 没有看到数据存储中的变化,并且将对旧数据进行操作。我错过了什么吗?

编辑:我还为 NSManagedObjectContextObjectsDidChangeNotification 设置了观察者,当它被调用时,我正在计算点的总和以将其反射(reflect)在 UI 上。不幸的是 sum 也不包含来自插入对象的点。这是我计算总和的代码:

+(NSInteger) getPoints: (NSManagedObjectContext *) context {
Stats * stats= [Stats get: context];

NSArray *args = [NSArray arrayWithObject:
[NSExpression expressionForKeyPath:@"pointsEarned"]];
NSExpression *ex = [NSExpression expressionForFunction:@"sum:"
arguments:args];

NSExpressionDescription *ed = [[NSExpressionDescription alloc] init];
[ed setName:@"result"];
[ed setExpression:ex];
[ed setExpressionResultType:NSInteger32AttributeType];

NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setPropertiesToFetch:[NSArray arrayWithObject:ed]];
[request setResultType:NSDictionaryResultType];

/*if([stats intervalStartDate]) {
NSPredicate *predicate =
[NSPredicate predicateWithFormat:@"when >= %@", [stats intervalStartDate]];
[request setPredicate:predicate];
}*/

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Reward"
inManagedObjectContext:context];
[request setEntity:entity];

NSArray *results = [context executeFetchRequest:request error:nil];

if(results && results.count > 0) {
NSDictionary *resultsDictionary = [results objectAtIndex:0];
NSNumber *resultValue = [resultsDictionary objectForKey:@"result"];
return [resultValue intValue];
} else {
return 0;
}
}

奇怪的是,当我在模拟器上停止应用程序并再次运行它时。我可以按预期看到所有点。

最佳答案

来自

reward.action = [NSNumber numberWithInt:action];

我假设“action”属性存储为 NSNumber。您应该在相应的谓词中使用相同的数据类型:

NSPredicate *actionPredicate = [NSPredicate predicateWithFormat:@"action = %@",
[NSNumber numberWithInt:action]];

已添加:关于“NSManagedObjectContextDidSaveNotification”与“NSManagedObjectContextObjectsDidChangeNotification”的问题:

NSDictionaryResultType 的获取请求仅获取持久存储中的当前状态,不考虑上下文中任何未决的更改、插入或删除。

您可以找到此信息,例如在 setIncludesPendingChanges: 的文档中。

这解释了为什么您的提取请求只能看到已保存的更改。

关于objective-c - 插入的对象不会反射(reflect)在 NSFetchRequest 的查询结果中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12287513/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com