Is it possible to shorten conditional expressions in cocoa so as not to reset the variable name?

I wonder if there is a way to shorten these conventions. I work with data packets and conditions sometimes get a little cumbersome. Here is a basic example:

Writing:

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

I would rather write:

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

If you define your enum so that the values โ€‹โ€‹have mutually exclusive bit patterns, for example:

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

Then you can check multiple values โ€‹โ€‹at once using binary OR | and binary AND & :

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

However, this will not work if you use compiler-generated sequential values โ€‹โ€‹for enum , because the values โ€‹โ€‹will overlap flags, for example, both 2 and 3 have the lowest bit, and together they often finish testing only one of the flags.

+1
source

Generally not. That is how C (and therefore Objective-C) works.

In this particular case, you can use the 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; } 

Whether this syntax is an improvement is up to you.

+2
source

You can enter values โ€‹โ€‹and use a temporary array. This achieves the goal of eliminating duplication in the conditional expression, but is unlikely to be optimized for the compiler.

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

should be equivalent to:

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

All Articles