我剛開始玩iOS開發和核心數據技術。插入的對象不反映在查詢結果與NSFetchRequest
我想要做的是將對象插入到核心數據,然後在相同的上下文中尋找新插入的對象運行獲取請求。
這裏是我使用插入對象的代碼:
+(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,當它被調用我計算點的總和,以反映它的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;
}
}
奇怪的是,當我停止在模擬器上的應用程序,並再次運行它。我可以按照我的預期看到所有的觀點。
我懷疑問題在於一個或兩個謂詞。嘗試註釋掉request.predicate =並查看是否可以添加兩行?如果不是,則診斷這些謂詞。 – CSmith
事實上,問題是與actionPredicate指出的答案 –
我有另一個難題,我把編輯 –