Iphone sdk — странное поведение при сравнении NSNumber

У меня есть проект, который выполняет несколько сетевых операций. Для простоты управления я дал каждой операции уникальный идентификатор, определенный как NSNumber, потому что мне нужно выполнять операции с объектами и массивом, и это проще:

#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]

затем я просто использовал среди своих проектных инструкций следующие, которые довольно хорошо работали в течение последнего года.

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

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

}

Однако сегодня я добавил последнюю операцию (номер 13), и все операции == приводят к ложным результатам только с этим числом! Я использовал отладчик, чтобы убедиться, что значение в порядке, но я могу получить условие истинно, только если я используйте: [opId isEqualToNumber: UPDATE_SERVICES_OPERATION], что довольно длинно.

Я понимаю, что NSNumber - это объект, и поэтому == может быть не лучшим выбором, но почему он работает со всеми другими операциями в проекте, но с # 13 не работает?

Любая помощь будет оценена.

Редактировать Ну, я пробовал с большими числами, и у меня та же проблема, но, например, если я переключаю номер UPDATE_SERVICES_OPERATION на другой номер операции, теперь он выполняет UPDATE_SERVICES_OPERATION, но не будет выполнять операцию, которую я переключил номер . Так почему же это не работает с более новыми номерами: S, или это просто проблема сборки на xcode? (я перезапущу и обновлю)


person htafoya    schedule 04.05.2012    source источник


Ответы (1)


Вы никогда не должны сравнивать NSNumber напрямую, как вы делаете здесь, потому что это объект, а не простой тип. Ваш текущий код зависит от равенства адресов памяти объектов, а не от их значения. Прочтите здесь для получения дополнительной информации Сравнение объектов в Obj-C.

Вы никогда не должны использовать == для сравнения на равенство объектов, вместо этого используйте функцию isEqual: для NSObject и обычно только в том случае, если вы хотите убедиться, что сравниваемые объекты являются одним и тем же экземпляром. Приведенный ниже код должен решить вашу проблему.


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

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

}
person Dave.B    schedule 04.05.2012
comment
Согласен, так и надо делать. Но, для меня вопрос остается открытым... почему меняется поведение? Я пытался разобраться сам, но пока не разобрался. - person C4 - Travis; 04.05.2012
comment
@C4 - Трэвис, если вы прочитали ответ на этот вопрос stackoverflow .com/questions/5054730/comparing-objects-in-obj-c вы увидите, что код, опубликованный оператором, сравнивает адреса памяти объектов. Есть много причин, по которым другие значения могут работать, а последнее нет, но есть вероятность, что все это несовместимо. Нам понадобится вся кодовая база для дальнейшего анализа. - person Dave.B; 04.05.2012