2012-07-30 76 views
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 

一如既往,感謝您的幫助。

回答

3

這種情況最常見的原因是,您在故事板或xib文件中定義了一個CalculatorViewController對象,並且圖形界面中的某個對象具有指向其名爲「description」的插座的鏈接。同時,您不再有該類別的代碼中的description插座。

這通常會通過追蹤界面構建器中的雜散引用並將其消除來解決。

+0

是的。這解決了它。我將'description'重命名爲'descriptionLabel',但最初並沒有擺脫「description」。 – 2012-07-31 04:18:54