Obj-C:if语句和NSString比较函数的效率和可读性

时间:2013-01-30 18:00:24

标签: objective-c if-statement nsstring

有效编码的最佳方法是什么,因为这将被递归调用,并且创建大量对象并不好。 +*-/, sin,cos,sqrt,pi and x,y,a,b应该放在三个独立的if statements中,而不像现在所有的一切都是分开的。同样为了便于阅读,制作包含4 isEqualToString的if语句并不是很好。

    NSString *operation = topOfStack;
    if ([operation isEqualToString:@"+"]) {

    } else if ([@"*" isEqualToString:operation]) {

    } else if ([operation isEqualToString:@"-"]) {

    } else if ([operation isEqualToString:@"/"]) {


    } else if ([operation isEqualToString:@"sin"]) {

    } else if ([operation isEqualToString:@"cos"]) {

    } else if ([operation isEqualToString:@"sqrt"]) {

    } else if ([operation isEqualToString:@"pi"]) {


    } else if ([operation isEqualToString:@"x"]) {

    } else if ([operation isEqualToString:@"y"]) {

    } else if ([operation isEqualToString:@"a"]) {

    } else if ([operation isEqualToString:@"b"]) {

    }

5 个答案:

答案 0 :(得分:3)

我不相信有最佳方法可以做到这一点,但这里有另一个选项来补充已经给出的答案。

创建一个NSDictionary,将您的操作名称(sin,sqrt, - )映射到选择器,如下所示:

NSDictionary *operations = @{
    @"sin": [NSValue valueWithPointer:@selector(operationSin:)],
    /* other operations here */
};

然后你的switch语句变成了查找。

NSString *operation = topOfStack;
if(operations[operation]) {
    SEL op = [operations[operation] pointerValue];
    [self performSelector:op withObject:value];  /* Or some approximation thereof */
}
else {
    /* Default action for unknown operation */
}

或者,您可以在已识别的操作上创建枚举,使用NSDictionary将操作名称映射到装入枚举值的NSNumber。

typedef NS_ENUM(NSUInteger, OperationType) {
    OperationTypeSin = 0L,
    OperationTypeSqrt,
    /* and so on */
    OperationTypeUnknown
};

/* And later...  */
NSDictionary *operations = @{
    @"sin": @(OperationTypeSin),
    /* you get the idea */
};

/* Finally ... */
NSString *operation = topOfStack;
OperationType opType = [operations[operation] unsignedIntegerValue];
switch(opType) {
    case OperationTypeSin:
        /* Much cleaner, and type-safe too */
}

答案 1 :(得分:2)

<强>的制备:
首先将NSString操作转换为int哈希码,将该哈希码存储在#define中 或不变。

<强>代码:

1)将NSString操作转换为int哈希码(tokenId) 2)然后在 tokenId 上执行switch语句。

int token = operationToToken(operation);
switch (token) {
case: OP_MINUS: break;
case: OP_SIN: break;
case: OP_COS: break;

}

答案 2 :(得分:1)

首先,可能会回退到C字符串,然后利用sincossqrtpia,{{ 1}},bx(差不多)都以不同的字符开头:

y

答案 3 :(得分:1)

如果你正在使用Objective-C,那么你可以用一些巧妙命名的选择器来做到这一点。

首先,创建一个对象来封装Operation

然后,创建一个-initWithOperation:(NSString *)op方法。在此方法中,将任何符号操作(*+等)转换为唯一的字符串标识符(仅限字母)。

然后,您可以调用NSSelectorFromString(stringOp),但如果您希望方法有参数,则必须自己附加:个字符。

拥有选择器后,您可以使用-performSelector:+performSelector:执行选择器,或手动调用选择器。

如果您使用与操作相同的名称命名每个选择器,则不需要任何ifswitch语句,但您必须处理发送无效选择器的情况

E.g:

@interface Operation : NSObject

- (id)initWithOperation:(NSString *)op;
- (void)performOperationWithValue:(float)value;
+ (float)sin:(float)value;
// ... Other operations
@property (nonatomic, copy) NSString *theOperation;

@end

@implementation Operation
- (id)initWithOperation(NSString *)op {
    self = [super init];
    if (self) {
        // Convert symbols to unique strings
        theOperation = [[NSString alloc] initWithString:op];
    }
    return self;
}

- (void)performOperationWithValue:(float)value {
    NSString *withOneParam = [self.theOperation stringByAppendingString:@":"];
    SEL sel = NSSelectorFromString(withOneParam);
    [Operation performSelector:withOneParam withObject:[NSNumber numberWithFloat:value]];
}

// Class methods are the actual operation implementation...

在上面的示例中,我假设您已将@"sin"传递给Operation对象。这只能在Objective-C中实现,因为您可以利用命名选择器。

答案 4 :(得分:0)

您可以为每个符号分配一个数字,并可以实现切换案例。