是否有可能缩短cocoa中的条件语句而不重新声明变量名?

时间:2013-02-16 19:40:51

标签: objective-c cocoa

想知道是否有办法简写这些条件。我正在处理数据包,条件有时会变得有点笨拙。这是一个基本的例子:

我写道:

if (message->messageType != kMessageTypeCutCardsArray && message->messageType != kMessageTypeQuit) {
    MessageInt message;
    message.message.messageType = kMessageTypeReceivedData;
    NSData *packet = [NSData dataWithBytes:&message length:sizeof(message)];
    [_game sendData:packet];
}

我宁愿写:

if (message->messageType != (kMessageTypeCutCardsArray || kMessageTypeQuit)) {
    MessageInt message;
    message.message.messageType = kMessageTypeReceivedData;
    NSData *packet = [NSData dataWithBytes:&message length:sizeof(message)];
    [_game sendData:packet];
}

3 个答案:

答案 0 :(得分:2)

总的来说,没有。这就是C(以及Objective-C)的工作方式。

在这种特定情况下,您可以使用switch语句:

switch (message->messageType)
{
    case kMessageTypeCutCardsArray:
    case kMessageTypeQuit:
        break;
    default:
        MessageInt message;
        message.message.messageType = kMessageTypeReceivedData;
        NSData *packet = [NSData dataWithBytes:&message length:sizeof(message)];
        [_game sendData:packet];
        break;
}

这种语法是否有所改进取决于你。

答案 1 :(得分:1)

如果您定义enum以使值具有相互排斥的位模式,则如下所示:

typedef enum : NSUInteger {
    kMessageTypeLoveLetter = 1 << 0,
    kMessageTypeBirthdayCard = 1 << 1,
    kMessageTypeVacationPostcard = 1 << 2,
    kMessageTypeCreditApplication = 1 << 3,
    kMessageTypeCharitySolicitation = 1 << 4
} MessageType;

然后,您可以使用二进制OR |和二进制AND &一次测试多个值:

MessageType msgType = kMessageTypeCreditApplication;

if( !(msgType & (kMessageTypeLoveLetter | kMessageTypeBirthdayCard)) ){
    // Nobody loves you.
}
if( (msgType & (kMessageTypeCreditApplication | kMessageTypeCharitySolicitation) ){
    // Someone wants your money.
}

但是,如果您使用编译器生成的enum连续值,这将不起作用,因为值将重叠为标志 - 例如,2和3都设置了最低位 - 并且将它们组合在一起通常最终只会测试其中一个标志。

答案 2 :(得分:0)

您可以装入值并使用临时数组。这实现了在条件中删除重复的目标,但不太可能对编译器具有可优化性。

if (message->messageType != kMessageTypeCutCardsArray && 
    message->messageType != kMessageTypeQuit) {

应该相当于:

if(![@[@(kMessageTypeCutCardsArray),@(kMessageTypeQuit)] 
     contains:@(message->messageType)]) {