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を使用してバグを探しますが、何かが表示される前にクラッシュが発生したときにどこで試すべきかわかりません。私が間違っていることについての考え?

これが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

いつものように、あなたの助けに感謝します。

4

1 に答える 1

3

これの最も一般的な原因はCalculatorViewController、ストーリーボードまたはxibファイルで定義されたオブジェクトがあり、グラフィカルインターフェイスの何かに「説明」と呼ばれるアウトレットへのリンクがあることです。その間、そのクラスのコードdescriptionにアウトレットはありません。

これは通常、Interface Builderで漂遊参照を追跡し、それを取り除くことで修正されます。

于 2012-07-30T19:09:55.080 に答える