简体   繁体   中英

Objective-C Trouble: EXC_BAD_ACCESS code=2

I'm trying to write a calculator program, but I'm running into this error when pressing a particular key that is linked to the function expressionEvaluation. My calculator works fine, but I am trying to add in the ability to use/store variables. For this, I use the expressionEvaluation button. However, as soon as I press the button linked to that method, the whole app crashes, and xcode gives me the error EXC_BAD_ACCESS code=2. I'm new to objective-c, so I'm not sure how to debug this error. As far as I can tell, though, the issue is with the line

double result = [CalculatorBrain evaluateExpression:self.brain.expression usingVariableValues:testValues];

...in my view controller. I set a break point before this line and it didn't crash, but setting it at this line resulted in the crash I'm experiencing. I tried to cut the code down below, and have included only the things directly linked to the expressionEvaluation button. Thank you for your help!

Here's the .h for my brain method:

//  CalculatorBrain.h

#import <Foundation/Foundation.h>

@interface CalculatorBrain : NSObject
- (void) pushOperand:(double)operand;
- (void) setVariableAsOperand:(NSString *)variableName;
- (void) performWaitingOperation;
- (double) performOperation:(NSString *)operation;

@property (readonly) id expression;
+ (double)evaluateExpression: (id)anExpression
         usingVariableValues: (NSDictionary *)variables;
+ (NSSet *)variablesInExpression:(id)anExpression;
+ (NSString *)descriptionOfExpression:(id)anExpression;

+ (id)propertyListForExpression:(id)anExpression;
+ (id)expressionForPropertyList:(id)propertyList;

@end

Here's the .m:

//  CalculatorBrain.m

#import "CalculatorBrain.h"
#define VARIABLE_PREFIX @"^"

@interface CalculatorBrain()
@property (nonatomic) double operand;
@property (nonatomic, strong) NSString *waitingOperation;
@property (nonatomic) double waitingOperand;
@property (nonatomic) double storedOperand;
@property (nonatomic) NSMutableArray *internalExpression;
@end

@implementation CalculatorBrain
@synthesize operand = _operand;                     //operand in use
@synthesize waitingOperation = _waitingOperation;   //waiting to be computed
@synthesize waitingOperand = _waitingOperand;       //waiting to be used
@synthesize storedOperand = _storedOperand;         //stored in memory
@synthesize internalExpression = _internalExpression; //private expression stored
@synthesize expression = _expression;

- (id) expression {;
    return [NSMutableArray arrayWithArray:self.internalExpression];
}

//here I have instance methods that add objects to the array internalExpression
//these work fine as far as I can tell

+ (double) evaluateExpression:(id)anExpression usingVariableValues:(NSDictionary *)variables {
    double result = 0;
    int count = [anExpression count];
    CalculatorBrain *brain;
    for (int i = 0; i < count; i++) {
        if([[anExpression objectAtIndex:i] isKindOfClass:[NSNumber class]]) {
            double operand = [[anExpression objectAtIndex:i] doubleValue];
            [brain pushOperand:operand];
        }
        if([[anExpression objectAtIndex:i] isKindOfClass:[NSString class]]) {
            NSString *string = [anExpression objectAtIndex:i];
            if([string characterAtIndex:0] == '^') {
                NSString* variable = [NSString stringWithFormat:@"%c",[string characterAtIndex:1]];
                double valueOfVariable = [[variables objectForKey:variable] doubleValue];
                [brain pushOperand:valueOfVariable];

            }
            else {
                NSString* operator = [anExpression objectAtIndex:i];
                result = [brain performOperation:operator];
            }
        }
    }
    return result;
}

@end

Here's the .h for my view controller:

//  CalcViewController.h

#import <UIKit/UIKit.h>
//view controller for calculator
@interface CalcViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *display;          //real-time display
@property (strong, nonatomic) IBOutlet UILabel *miniDisplay;    //past display
@property (strong, nonatomic) IBOutlet UILabel *memDisplay;     //display stored digits
- (IBAction)digitPressed:(UIButton *)sender;    //pressed number
- (IBAction)operandPressed:(UIButton *)sender;  //pressed operation
- (IBAction)variablePressed:(UIButton *)sender; //pressed variable
- (IBAction)expressionEvaluation:(UIButton *)sender; //evaluate expression with variables
@end

Here's the .m:

//  CalcViewController.m

#import "CalcViewController.h"
#import "CalculatorBrain.h"

@interface CalcViewController ()
@property (nonatomic, strong) CalculatorBrain *brain;
@property (nonatomic) BOOL userIsInTheMiddleOfTypingANumber;
@end

@implementation CalcViewController
- (CalculatorBrain *) brain {
    if (!_brain) _brain = [[CalculatorBrain alloc] init];
    return _brain;
}

- (IBAction)expressionEvaluation:(UIButton *)sender {
    NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:@"x", 2, @"y", 3, @"z", 4, nil];
    double result = [CalculatorBrain evaluateExpression:self.brain.expression usingVariableValues:testValues];
    NSString *resultString = [NSString stringWithFormat:@"%g", result];
    self.display.text = resultString;
}


@end

EDIT: Just as a side note, I am not getting any errors, only one warning: incomplete implementation. This is because I haven't finished a couple class methods yet, but I don't think it is causing the crash.

NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:@"x", 2, @"y", 3, @"z", 4, nil];

turned out to be the erroneous line. It should have been:

NSDictionary* testValues = [NSDictionary dictionaryWithObjectsAndKeys:@"x", [NSNumber numberWithInt:2], @"y", [NSNumber numberWithInt:3], @"z", [NSNumber numberWithInt:4], nil];

Thanks to everyone who helped!

通过在xCode中添加异常断点,您将获得更多有关引发异常的代码行的信息。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM