类方法,保存状态,更好的注册函数方式

时间:2012-02-02 01:57:35

标签: objective-c

我正在进行一项涉及制作RPN计算器的作业。我目前正在使用类方法来检查字符串是否是如下操作:

+ (NSSet *) noOpOperations {
    return [NSSet setWithObjects:@"π", nil];
}

+ (NSSet *) unaryOperations {
    return [NSSet setWithObjects:@"sin",@"cos",@"log",@"+/-", nil];
}

+ (NSSet *) binaryOperations {
    return [NSSet setWithObjects:@"+",@"-",@"*",@"/", nil];
}
+ (NSSet *) operations {
    /* surely there is a better way - is it possible to save this call and reuse it?  Or what about having the objects register themselves so you can add operations more easily? */
    return [[self noOpOperations] setByAddingObjectsFromSet:
            [[self unaryOperations] setByAddingObjectsFromSet:
             [self binaryOperations]]];
}

+ (BOOL) isOperation:operand {
    return [[self operations] containsObject:operand]; 
}

我认为最好实现一种函数注册表系统,以允许从项目中的另一个位置动态添加操作,但我认为它需要一个类变量。有没有比我现在这样做更好的方法呢?

1 个答案:

答案 0 :(得分:1)

我的个人解决方案适用于以下情况:

#define INT_OBJ(x) [NSNumber numberWithInt:x]

@implementation MyClass

static NSDictionary *operations;

enum {
    kOperationNoOp = 1,
    kOperationUnaryOp,
    kOperationBinaryOp,
};

+(void) initialize
{
    operations = [NSDictionary dictionaryWithObjectsAndKeys:@"π",   INT_OBJ(kOperationNoOp), 

                                                            // unary operations
                                                            @"sin", INT_OBJ(kOperationUnaryOp), 
                                                            @"cos", INT_OBJ(kOperationUnaryOp), 
                                                            @"log", INT_OBJ(kOperationUnaryOp), 
                                                            @"+/-", INT_OBJ(kOperationUnaryOp), 

                                                            // binary operations
                                                            @"+",   INT_OBJ(kOperationBinaryOp), 
                                                            @"-",   INT_OBJ(kOperationBinaryOp), 
                                                            @"*",   INT_OBJ(kOperationBinaryOp), 
                                                            @"/",   INT_OBJ(kOperationBinaryOp), nil];
}

-(BOOL) isNoOpOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationNoOp;
}

-(BOOL) isUnaryOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationUnaryOp;
}

-(BOOL) isBinaryOperation:(NSString *) arg
{
    return [[operations objectForKey:arg] intValue] == kOperationBinaryOp;
}

-(BOOL) isAnOperation:(NSString *) arg
{
    // if objectForKey: returns nil, intValue will return 0, telling us that the input is not an operation
    return [[operations objectForKey:arg] intValue] != 0;
}

@end

我发现它非常简单易用。