kvnn
kvnn

Reputation: 350

Calling a class method from a View gives: "Unrecognized selector sent to class"

I'm trying to call a class method that is defined in an imported header file.

When I run the code below, I get this error in the View on the "double *result = ..." line:

+[CalculatorBrain runProgram:usingVariableValues:]: unrecognized selector sent to class 0x6908

** CalculatorViewController.m **

#import "CalculatorViewController.h"
#import "CalculatorBrain.h"

@interface CalculatorViewController()

@property (nonatomic, strong) CalculatorBrain *brain;
@property (nonatomic, strong) NSMutableDictionary *variableValues;

@end

@implementation CalculatorViewController

@synthesize brain = _brain;
@synthesize variableValues = _variableValues;

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

- (NSMutableDictionary *)variableValues {
    if (!_variableValues) {
        _variableValues = [[NSMutableDictionary alloc] init];
    }
    return _variableValues;
}

- (IBAction)enterPressed {

    double *result = [CalculatorBrain runProgram:[self.brain program] usingVariableValues:[self variableValues]];

}

** CalculatorBrain.h **

#import <UIKit/UIKit.h>

@interface CalculatorBrain : NSObject

+ (double *)runProgram:(id)program usingVariableValues:(NSDictionary *)variableValues;

@property (readonly) id program;


@end

** CalculatorBrain.m **

#import "CalculatorBrain.h"

@interface CalculatorBrain()
    @property (nonatomic, strong) NSMutableArray *programStack;
@end

@implementation CalculatorBrain

@synthesize programStack = _programStack;


... other code ...

+ (double)runProgram:(id)program :(NSDictionary *) usingVariableValues 
{

    NSLog(@"variableValues is %@", usingVariableValues);

    NSMutableArray *stack;

    if ([program isKindOfClass:[NSArray class]]) {

        stack = [program mutableCopy];

        NSLog(@"runProgram");

        // if vars are passed in
        if ([usingVariableValues isKindOfClass:[NSDictionary class]]) {

            NSLog(@"vars are passed in: %@", usingVariableValues);

            id obj;
            int index = 0;

            NSEnumerator *enumerator = [program objectEnumerator];

            // for every obj in programStack
            while ((obj = [enumerator nextObject])) {

                id varVal = [usingVariableValues objectForKey:(obj)];

                // test
                NSLog(@"usingVariableValues objectForKey:(obj) is %@", varVal);

                // if the obj is a variable key
                if (!varVal) {
                    varVal = 0;

                    NSLog(@"varVal is false");
                }

                NSLog(@"Replacing object at index %@ of stack with var %@", index, varVal);


                // replace the variable with value from usingVariableValues OR 0
                [stack replaceObjectAtIndex:(index) withObject:varVal];

                index += 1;

            }
        }

    }

    return [self popOperandOffStack:stack];
}

Upvotes: 0

Views: 143

Answers (1)

vikingosegundo
vikingosegundo

Reputation: 52237

+ (double *)runProgram:(id)program usingVariableValues:(NSDictionary *)variableValues;

Is defined as a class method, but you call it as an object method

 double *result = [self.brain runProgram:[self.brain program] usingVariableValues:[self variableValues]];

To call it on the class do:

 double *result = [[self.brain class] runProgram:[self.brain program] usingVariableValues:[self variableValues]];

Or

double *result = [CalculatorBrain runProgram:[self.brain program] usingVariableValues:[self variableValues]];

You changed your code, indicating, that the method is still not found. Did you implement it?


If it is implemented, then you might have to add the implementation file (aka .m) to the target in Xcode.

By the way,: probably you want your method to return a double not a double*, a pointer to a double.


your header has a signature:

+ (double *)runProgram:(id)program usingVariableValues:(NSDictionary *)variableValues;

While your implementation has

+ (double)runProgram:(id)program :(NSDictionary *) usingVariableValues 

They are not identical:

  1. The header promisses a pointer to a double to be returned. You don't want that.

  2. They don't even have the same name +runProgram:usingVariableValues: vs +runProgram::

Upvotes: 1

Related Questions