我真的很困惑为什么我的PFQuery不会返回任何结果。首先让我向您展示我最初做过的事情,这段代码完美无缺。
-(IBAction)Answer2:(id)sender{
NSString *quizString = [NSString stringWithFormat:@"%i",CategoryLoaded];
NSString *questionString = [NSString stringWithFormat:@"%i",QuestionSelected];
NSString *answerString = [NSString stringWithFormat:@"b"];
PFObject *newAnswerVote = [PFObject objectWithClassName:@"QuizData"];
newAnswerVote[@"quiz"] = quizString;
newAnswerVote[@"question"] = questionString;
newAnswerVote[@"answer"] = answerString;
[newAnswerVote saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
[newAnswerVote incrementKey:@"Total"];
}
else{
}
}
];
PFQuery *queryb = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryb whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryb whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryb whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"b"]];
[queryb getFirstObjectInBackgroundWithBlock:^(PFObject *total, NSError *error){
[total incrementKey:@"Total"];
NSString *myVote = total[@"Answer"];
[total saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
PFQuery *queryForHighestVoteb = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryForHighestVoteb whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryForHighestVoteb whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryForHighestVoteb orderByDescending:@"Total"];
[queryForHighestVoteb getFirstObjectInBackgroundWithBlock:^(PFObject *firstAnswerStorageObject, NSError *error){
if (nil != error) {
// query failed
} else {
NSString *highestVote = firstAnswerStorageObject[@"Answer"];
if (myVote == highestVote) {
[self RightAnswer];
} else {
[self WrongAnswer];
}}}];
}}];
}];
}
现在这是我正在使用的代码。使用先前使用的相同PFQuery,但稍后使用添加的算法。但是,此查询不会检索任何结果。给我VoteAScore,VoteBScore,VoteCScore和VoteDScore的0值。离开我的错误:
EXC_arithmetic(code = exc_i386_div,subcode = 0x0)
我不知道是什么导致了它。
-(void)GetTotalVotes{
PFQuery *querya = [PFQuery queryWithClassName:@"AnswerStorage"];
[querya whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[querya whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[querya whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"a"]];
[querya getFirstObjectInBackgroundWithBlock:^(PFObject *atotal, NSError *error){
[atotal incrementKey:@"Total"];
[atotal incrementKey:@"Test"];
[atotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
NSUInteger answerATotal = [atotal[@"Total"]intValue];
VoteAScore = answerATotal;
[atotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
}
else{}
}];}
else{}
}];}];
PFQuery *queryb = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryb whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryb whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryb whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"b"]];
[queryb getFirstObjectInBackgroundWithBlock:^(PFObject *btotal, NSError *error){
[btotal incrementKey:@"Total"];
[btotal incrementKey:@"Test"];
[btotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
NSUInteger answerBTotal = [btotal[@"Total"]intValue];
VoteBScore = answerBTotal;
[btotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
}
else{}
}];}
else{}
}];}];
PFQuery *queryc = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryc whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryc whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryc whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"c"]];
[queryc getFirstObjectInBackgroundWithBlock:^(PFObject *ctotal, NSError *error){
[ctotal incrementKey:@"Total"];
[ctotal incrementKey:@"Test"];
[ctotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
NSUInteger answerCTotal = [ctotal[@"Total"]intValue];
VoteCScore = answerCTotal;
[ctotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
}
else{}
}];}
else{}
}];}];
PFQuery *queryd = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryd whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryd whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryd whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"d"]];
[queryd getFirstObjectInBackgroundWithBlock:^(PFObject *dtotal, NSError *error){
[dtotal incrementKey:@"Total"];
[dtotal incrementKey:@"Test"];
[dtotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
NSUInteger answerDTotal = [dtotal[@"Total"]intValue];
VoteDScore = answerDTotal;
AllVoteScore = VoteAScore + VoteBScore + VoteCScore + VoteDScore;
[dtotal saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
}
else{}
}];}
else{}
}];}];}
-(IBAction)Answer1:(id)sender{
NSString *quizString = [NSString stringWithFormat:@"%i",CategoryLoaded];
NSString *questionString = [NSString stringWithFormat:@"%i",QuestionSelected];
NSString *answerString = [NSString stringWithFormat:@"a"];
PFObject *newAnswerVote = [PFObject objectWithClassName:@"QuizData"];
newAnswerVote[@"quiz"] = quizString;
newAnswerVote[@"question"] = questionString;
newAnswerVote[@"answer"] = answerString;
[newAnswerVote saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
}
else{
}
}
];
PFQuery *querym = [PFQuery queryWithClassName:@"AnswerStorage"];
[querym whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[querym whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[querym whereKey:@"Answer" equalTo: [NSString stringWithFormat:@"a"]];
[querym getFirstObjectInBackgroundWithBlock:^(PFObject *total, NSError *error) {
[total incrementKey:@"Total"];
[total incrementKey:@"Test"];
[total saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded == YES){
PFQuery *queryForHighestVotec = [PFQuery queryWithClassName:@"AnswerStorage"];
[queryForHighestVotec whereKey:@"Quiz" equalTo: [NSString stringWithFormat:@"%i",CategoryLoaded]];
[queryForHighestVotec whereKey:@"Question" equalTo: [NSString stringWithFormat:@"%i",QuestionSelected]];
[queryForHighestVotec orderByDescending:@"Total"];
[queryForHighestVotec getFirstObjectInBackgroundWithBlock:^(PFObject *firstAnswerStorageObject, NSError *error){
if (nil != error) {
// query failed
} else {
[self GetTotalVotes];}
}];
}}];
}];
if (VoteAScore > VoteBScore || VoteAScore > VoteCScore || VoteAScore > VoteDScore || VoteBScore > VoteCScore || VoteBScore > VoteDScore){
Outcome = 0;
}
else if (VoteAScore > VoteBScore || VoteAScore > VoteCScore || VoteAScore > VoteDScore || VoteCScore > VoteBScore || VoteCScore > VoteDScore){
Outcome = 1;
}
else if (VoteAScore > VoteBScore || VoteAScore > VoteCScore || VoteAScore > VoteDScore || VoteDScore > VoteBScore || VoteDScore > VoteCScore){
Outcome = 2;
}
else if (VoteBScore > VoteAScore || VoteBScore > VoteCScore || VoteBScore > VoteDScore){
Outcome = 3;
}
else if (VoteCScore > VoteAScore || VoteCScore > VoteBScore || VoteCScore > VoteDScore){
Outcome = 4;
}
else if (VoteDScore > VoteAScore || VoteDScore > VoteBScore || VoteDScore > VoteCScore){
Outcome = 5;
}
switch (Outcome)
{
case 0:
OneFraction = VoteAScore/AllVoteScore;
TwoFraction = VoteBScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber + AddScore;
[self RightAnswer];
break;
case 1:
OneFraction = VoteAScore/AllVoteScore;
TwoFraction = VoteCScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber + AddScore;
[self RightAnswer];
break;
case 2:
OneFraction = VoteAScore/AllVoteScore;
TwoFraction = VoteDScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber + AddScore;
[self RightAnswer];
break;
case 3:
OneFraction = VoteBScore/AllVoteScore;
TwoFraction = VoteAScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber - AddScore;
[self WrongAnswer];
break;
case 4:
OneFraction = VoteCScore/AllVoteScore;
TwoFraction = VoteAScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber - AddScore;
[self WrongAnswer];
break;
case 5:
OneFraction = VoteDScore/AllVoteScore;
TwoFraction = VoteAScore/AllVoteScore;
Margin = OneFraction - TwoFraction;
InvertedMargin = 1 - Margin;
AddScore = Margin * 1000;
ScoreNumber = ScoreNumber - AddScore;
[self WrongAnswer];
break;
}}
答案 0 :(得分:0)
除了代码中的许多问题(请参阅上面的评论)之外,您还必须记住getFirstObjectInBackgroundWithBlock:
,正如其名称所暗示的,在后台运行。所以当它将控制权返回给它的调用者时,什么也没发生,只有在稍后才能用结果调用该块。
所以你不能考虑因为那个调用返回了,所以调用了块,它返回的数据已经可用并保存(稍后会发生)。
您需要使用PFQuery
调用的同步版本(但如果您从主线程调用它们,这将阻止您的UI),或者更好的是,包含任何依赖于这些调用的结果的逻辑在提供的块中调用,而不是在这些调用之后运行的代码中调用。
答案 1 :(得分:0)
由于您在another question的评论中要求我建议解决此问题,我的回答是:
jcaron是对的:您的代码正在向Parse发送多个查询,并且在回调变量设置之前使用返回变量。因此它们为零,你得到除零例外 您评估查询结果的代码部分只能在所有查询完成后执行。
您可以使用两种方法:
1)按顺序嵌套查询
在主线程中,仅发出alpha
。在import
(如果成功)的回调中,发出beta
等问题,最后在上次查询的回调中,评估结果。
这可行,但由于嵌套在多个级别上,代码看起来会令人困惑,而且由于查询是按顺序发出的,因此速度很慢。
2)同时执行查询
定义一种评估结果的方法,因为它现在可以从代码的不同部分调用。一旦所有查询执行了他们的回调,就必须立即调用它
在主线程中,设置变量querya
并将其设置为将同时执行的查询数。然后在主线程中一个接一个地发出查询(比如在代码中)。
虽然您按特定顺序发出查询,但可以按任何顺序调用回调(如果松开连接,则根本不调用)。因此,您的查询的任何回调可能是最后一次回调
要检查哪一个实际上是最后一个,你可以在每个回调中递减querya
,当它在某个回调中达到零时,你的方法来评估结果是从这个回调中执行的。
但是你应该知道这是异步代码,它的部分可以或多或少地随时执行。例如,语句queryb
不是原子的,如果其中2个语句在2个回调中“同时”执行,__block NSUInteger nrOfExpectedServerResponses
可能没有减少2,而只减1。为避免此类危险,您必须将此声明括在nrOfExpectedServerResponses
块中,例如nrOfExpectedServerResponses--
。
当然,在这两种情况下,您都必须处理所有可能的错误。你可以,例如设置一个超时计时器,如果查询未在合理的时间内完成,您的应用程序将继续运行。