0
我很愚蠢,並沒有按照我的程序進行不斷的測試,所以現在我不確定錯誤發生在哪裏。我正在使用可編程計算器。當我運行,它顯示任何內容之前崩潰,並給了我這個消息:鍵值編碼合規
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<CalculatorViewController 0x6a405a0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key description.'
我使用的NSLog去尋找bug,但我不知道在哪裏可以試試它的崩潰之前的任何節目發生向上。關於我在做什麼錯的想法?
這裏的CalculatorViewController.m,一些額外的屬性聲明未完成,註釋掉的代碼,我省略了:
#import "CalculatorViewController.h"
#import "CalculatorBrain.h"
@interface CalculatorViewController()
@property (nonatomic) BOOL userIsEnteringNumber;
@property (nonatomic) BOOL numberIsNegative;
@property (nonatomic,strong) CalculatorBrain *brain;
@end
@implementation CalculatorViewController
@synthesize display = _display;
@synthesize descriptionLabel = _descriptionLabel;
@synthesize userIsEnteringNumber = _userIsEnteringNumber;
@synthesize numberIsNegative;
@synthesize brain = _brain;
-(CalculatorBrain *)brain
{
if (!_brain) _brain = [[CalculatorBrain alloc] init];
return _brain;
}
//This adds a pressed digit to the display label.
- (IBAction)digitPressed:(UIButton *)sender
{
NSString *digit = sender.currentTitle;
//Enter digit if it wouldn't create a two-decimal-point case.
NSRange range = [self.display.text rangeOfString:@"."];
if (range.location==NSNotFound || (![digit isEqualToString:@"."]))
if (self.userIsEnteringNumber)
{
self.display.text = [self.display.text stringByAppendingString:digit];
self.descriptionLabel.text = [self.display.text stringByAppendingString:@" "];
}
else
{
self.descriptionLabel.text = [self.descriptionLabel.text stringByAppendingString:digit];
self.descriptionLabel.text = [self.descriptionLabel.text stringByAppendingString:@" "];
if (![sender.currentTitle isEqualToString:@"."])
{
self.display.text = digit;
}
else
{
self.display.text = @"0.";
}
self.userIsEnteringNumber = YES;
}
}
//This sets up an operation.
- (IBAction)operationPressed:(UIButton *)sender
{
if (self.userIsEnteringNumber) [self enterPressed];
NSString *operation = sender.currentTitle;
double result = [self.brain performOperation:operation];
self.display.text = [NSString stringWithFormat:@"%g",result];
{
NSString *descr = [self.brain description];
self.descriptionLabel.text = descr;
}
}
- (IBAction)enterPressed
{
NSCharacterSet *set = [NSCharacterSet decimalDigitCharacterSet];
NSRange range = [self.display.text rangeOfCharacterFromSet:set];
if (range.location==NSNotFound)
{
[self.brain pushOperandAsVariable:self.display.text];
}
else
{
[self.brain pushOperand:[self.display.text doubleValue]];
}
self.userIsEnteringNumber = NO;
}
@end
而這裏的CalculatorBrain.m:
#import "CalculatorBrain.h"
@interface CalculatorBrain()
@property (nonatomic, strong) NSMutableArray *programStack;
@property (nonatomic,strong)NSDictionary *variableValues;
@end
@implementation CalculatorBrain
@synthesize programStack = _programStack;
@synthesize variableValues = _variableValues;
- (NSMutableArray *)programStack
{
if (!_programStack) _programStack = [[NSMutableArray alloc] init];
return _programStack;
}
- (id)program
{
return [self.programStack copy];
}
//Here are the two types of pushes that the ViewController can implement. First, operand pushes . . .
- (void)pushOperand:(double)operand
{
[self.programStack addObject:[NSNumber numberWithDouble:operand]];
}
//. . . and then variable pushes.
- (void) pushOperandAsVariable:(NSString *)variable
{
//Create dictionary
//Move this later on to ViewController but for now leave where it is....
NSMutableArray *variablesUsed = [[NSMutableArray alloc] init];
NSArray *objects = [[NSArray alloc] initWithObjects:[NSNumber numberWithDouble:3],[NSNumber numberWithDouble:4.1],[NSNumber numberWithDouble:-6],[NSNumber numberWithDouble:4.5298], [NSNumber numberWithDouble:3.14159], nil];
NSArray *keys = [[NSArray alloc] initWithObjects:@"x",@"y",@"z",@"foo", @"π", nil];
NSDictionary *variableValues = [[NSDictionary alloc] initWithObjects:objects forKeys:keys];
//Check program for keys
NSNumber *operand;
for (int i=0; i<keys.count; i++)
{
if ([[keys objectAtIndex:i] isEqual:variable])
[variablesUsed addObject:variable];
operand = [variableValues objectForKey:variable];
}
[self.programStack addObject:operand];
}
- (double)performOperation:(NSString *)operation
{
[self.programStack addObject:operation];
return [[self class] runProgram:self.program];
}
+ (double)popOffStack:(NSMutableArray *)stack
{
double result = 0;
id topOfStack = [stack lastObject];
if (topOfStack) [stack removeLastObject];
if ([topOfStack isKindOfClass:[NSNumber class]])
{
result = [topOfStack doubleValue];
}
//Here are the results for various operations.
else if ([topOfStack isKindOfClass:[NSString class]])
{
NSString *operation = topOfStack;
if ([operation isEqualToString:@"+"])
{
result = [self popOffStack:stack] +
[self popOffStack:stack];
}
else if ([@"*" isEqualToString:operation])
{
result = [self popOffStack:stack] *
[self popOffStack:stack];
}
else if ([operation isEqualToString:@"-"])
{
double subtrahend = [self popOffStack:stack];
result = [self popOffStack:stack] - subtrahend;
}
else if ([operation isEqualToString:@"/"])
{
double divisor = [self popOffStack:stack];
if (divisor) result = [self popOffStack:stack]/divisor;
}
else if ([operation isEqualToString:@"sin"])
{
result = sin([self popOffStack:stack]);
}
else if ([operation isEqualToString:@"cos"])
{
result = cos([self popOffStack:stack]);
}
else if ([operation isEqualToString:@"√"])
{
result = sqrt([self popOffStack:stack]);
}
else if ([operation isEqualToString:@"π"])
{
result = M_PI;
}
}
return result;
}
+ (double)runProgram:(id)program
{
//Run program.
NSMutableArray *mutableCopyOfProgram;
if ([program isKindOfClass:[NSArray class]])
{
mutableCopyOfProgram = [program mutableCopy];
return [self popOffStack:mutableCopyOfProgram];
}
else return 0;
}
@end
一如既往,感謝您的幫助。
是的。這解決了它。我將'description'重命名爲'descriptionLabel',但最初並沒有擺脫「description」。 – 2012-07-31 04:18:54