2

I have a project which does several network operations. For easy control I have given each operation a unique Id, defined as a NSNumber because i have to perform operations with objects and Array and is easier this way:

#define LOGIN_OPERATION                     [NSNumber numberWithInt:0]
#define REGISTER_USER_OPERATION             [NSNumber numberWithInt:1]
#define VERIFY_USER_OPERATION               [NSNumber numberWithInt:2]
#define REGISTER_USER_DATA_OPERATION        [NSNumber numberWithInt:3]
#define FORGOT_PASSWORD_OPERATION           [NSNumber numberWithInt:4]
#define PASSTIME_REGISTER_OPERATION         [NSNumber numberWithInt:5]
#define PASSTIME_VERIFY_TOKEN_OPERATION     [NSNumber numberWithInt:6]
#define PASSTIME_OPERATION                  [NSNumber numberWithInt:7]
#define SERVICES_OPERATION                  [NSNumber numberWithInt:8]
#define MAIL_SUPPORT_OPERATION              [NSNumber numberWithInt:9]
#define UPDATE_USER_INFO_OPERATION          [NSNumber numberWithInt:10]
#define OBTAIN_CACS_OPERATION               [NSNumber numberWithInt:11]
#define GET_PREPAID_BALANCE_OPERATION       [NSNumber numberWithInt:12]
#define UPDATE_SERVICES_OPERATION           [NSNumber numberWithInt:13]

then I simply used among my project instructions as the following, which has worked pretty well during the last year.

- (void) processNetworkResponseForOperation: (NSNumber*) opId {

    if (opId == SERVICES_OPERATION) {
        //do something
    } else if (opId == UPDATE_SERVICES_OPERATION) {
        //do something
    }

}

However today i added the last operation (number 13) and all the == operations result false, just with that number!, i have used the debugger to assure that the value is ok, but i can only get the condition to true if I use: [opId isEqualToNumber: UPDATE_SERVICES_OPERATION] which is pretty long.

I understand that NSNumber is an object and thus == may not be the best choise, but why does it works with all other operations among the project but with #13 wont work?

Any help will be appreciated.

Edit Well i tried with bigger numbers and i have the same problem, but for example if I switch theUPDATE_SERVICES_OPERATION number with another op number, it now does the UPDATE_SERVICES_OPERATION but it wont do the operation which i switched the number. So why doesn't it work with newer numbers :S, or is it just a build problem on xcode? (i will restart and update)

htafoya
  • 18,261
  • 11
  • 80
  • 104

1 Answers1

11

You should never compare an NSNumber directly like you are doing here because it is an object and not a simple type. Your current code is depending on the equality of the objects memory addresses not their value. Read here for more information Comparing objects in Obj-C.

You should never use == to compare for object equality but instead the isEqual: function on NSObject and usually only if you want to be sure the objects you are comparing are the same instance. The code below should fix your problem.


- (void) processNetworkResponseForOperation: (NSNumber*) opId {

    if ([opId intValue] == [SERVICES_OPERATION intValue]) {
        //do something
    } else if ([opId intValue] == [UPDATE_SERVICES_OPERATION intValue]) {
        //do something
    }

}
Community
  • 1
  • 1
Dave.B
  • 6,632
  • 1
  • 19
  • 20
  • I agree, this is how it should be done. But, for me the question is still open... why does the behaviour change? I tried figuring it out myself but haven't got a clue yet. – C4 - Travis May 04 '12 at 17:03
  • @C4 - Travis if you read the answer to this question http://stackoverflow.com/questions/5054730/comparing-objects-in-obj-c you'll see that the code the op posted compares the memory address of the objects. There are many reasons that the other values may work while the last does not but chances are the whole thing is inconsistent. We would need the whole code base to analyze further. – Dave.B May 04 '12 at 17:11