1

我正在做cs193p课程的基础计算器作业,但我的
+evaluateExpression:usingVariables:方法不起作用。它总是返回 0。

这是我的方法:

+ (double)evaluateExpression: (id)anExpression usingVariablevalues: (NSDictionary *)variables {
CalculatorBrain *worker = [[[CalculatorBrain alloc] init] autorelease];
double returnValue = 10.0;
if ([anExpression isKindOfClass:[NSMutableArray class]]) {
    for (id term in anExpression) {
        NSLog(@"%f", returnValue);         // breakpoint
        if ([term isKindOfClass:[NSString class]]) {                                    // string
            if ([term hasPrefix:@"%"] && [term length] == 2) {                          // variable
                double value = [(NSNumber *)[variables objectForKey:[term substringFromIndex:1]] doubleValue];
                NSLog(@"Variable: %@, value: %d", [term substringFromIndex:1], value);
                [worker setOperand:value];
            }
            else if ([term length] == 1) {                                              // operation
                returnValue = [worker performOperation:term];
            }
            else {
                NSLog(@"Invalid expression.\n\tMultiple character operation found: %@", term);
            }
        }
        else if ([term isKindOfClass:[NSNumber class]]) {                                   // operand
            double value = [term doubleValue];
            [worker setOperand:value];
        }
        else {
            NSLog(@"Invalid expression.\n\tWrong type in expression: %@, The value is: %@.",[term class], term);    // Wrong type in expression
        }

    }
}
else {
    NSLog(@"Invalid expression.\n\tThe expression is of the wrong type: %@.", [anExpression class]);    // expression is of wrong type
}
//returnValue = worker.operand;
return returnValue;
}

有什么提示吗?它总是返回 0。

/* Ouput from Console */
2012-06-27 20:01:05.487 Calculator[2823:207] 0
2012-06-27 20:01:05.488 Calculator[2823:207] 0
2012-06-27 20:01:05.489 Calculator[2823:207] 0
2012-06-27 20:01:05.490 Calculator[2823:207] Variable: x, value: 0
2012-06-27 20:01:05.490 Calculator[2823:207] 0
2012-06-27 20:01:05.491 Calculator[2823:207] 0
2012-06-27 20:01:05.491 Calculator[2823:207] 0

注意:我在开始时将 returnValue 设置为 10.0 以检查它是否完全改变了。

更新:

我发现它从字典中得到 0。我认为调用代码是原因:

- (IBAction) performSampleExpression {
    NSMutableArray *expr = [[NSMutableArray alloc] init]; 
    [expr addObject:[NSNumber numberWithDouble:3.0]];
    [expr addObject:@"+"];
    [expr addObject:@"%x"];
    [expr addObject:@"*"];
    [expr addObject:[NSNumber numberWithDouble:4.0]];

    NSDictionary *varsdict = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithDouble:10.0], @"x", nil];

    double result = [CalculatorBrain evaluateExpression:expr usingVariablevalues:varsdict];
    if (!result) NSLog(@"result = nil");
    NSLog(@"%f", result);

    display.text = [NSString stringWithFormat:@"%f", result];
    [expr release];
}

结果不是零。

更新 2:

使用调试器(很好的提示。这可能会解决它。)我发现了一些奇怪的东西:

在这条线上:(第一次)

returnValue = worker.operand;

它说 returnValue 仍然是 10,而不是 3(worker.operand IS)。
作业失败了,还是应该这样?(就是想)。

更新 3:

好的,这里发生了一些非常奇怪的事情:我在 return 语句的最后一行设置了一个断点+evaluateExpression:usingVariables:,它说
returnValue = 4
这意味着,实际问题出在-performSampleExpression. 我究竟做错了什么?

更新 4:

变身帮@"%d", double@"%f", double大忙。这就解释了奇怪的控制台输出。但是,它解决了它,因为我更新了显示,如显示[setText:@"%d", result];导致我的双精度显示为 0 由于错误的演员阵容。
我通过使用调试器发现了这一点,因此建议的人实际上解决了它。(我要求的是hints,而不是解决方案。毕竟,功课是要学习的)。

4

3 回答 3

1

您是否尝试过一次单步执行代码并检查变量值?

于 2012-06-27T14:08:44.390 回答
1

可能的问题可以显示在:

 returnValue = [worker performOperation:term];

returnValue = worker.operand;

您应该在此行(或下面的行)中停止调试器,并注意如何更改您的值returnValue

屏幕

您停止应用点击屏幕上的位置,应用停止,然后使用 F6(或 Fn+F6)跳转到下一行。在下方(在控制台中),您可以看到该值。

编辑

您可以尝试此解决方案 - 将分配更改为:

CalculatorBrain *worker = [[[CalculatorBrain alloc] init] autorelease];

并删除行:

 [worker release];

此版本在返回之前可能会在没有 NSCopying @protocol 的情况下引起问题。

自动释放和 NSCopying

为了更好地理解编译此代码:

NSMutableArray *arrOne = [[NSMutableArray alloc] initWithObjects:@"1",@"2", nil];
NSMutableArray *arrTwo = [[NSMutableArray alloc] init];

arrTwo = arrOne;
[arrOne addObject:@"3"]; //After that arrTwo "shold" be 1,2 and arrOne 1,2,3. No! There both 1,2,3!

for(int i=0;i<[arrTwo count];i++)
    NSLog(@"%@",[arrTwo objectAtIndex:i]);

因此,您可以考虑如何分配变量。在上面的示例中,释放内存不应该影响返回值,但是通过使用带有返回对象的自动释放,您不必分配任何东西。

于 2012-06-27T14:15:23.870 回答
0

我在您的代码中看到了一点内存泄漏:

所以,而不是这个: [worker release];

试试这一行:[worker autorelease];

我不确定它是否导致了问题,但您的版本肯定看起来不太好。

于 2012-06-27T15:29:07.520 回答