Равенство примитивного значения NSNumber против isEqualToNumber с литералами Obj-C

Теперь, когда у нас есть литералы NSNumber с поддержкой компилятора в Objective-C, есть ли предпочтительный способ сравнить NSNumber с известным целочисленным значением?

Старый способ[myNumber integerValue] == 5

Теперь мы можем сделать [myNumber isEqualToNumber:@5] или даже [myNumber isEqualToNumber:@(someVariable)],

Есть ли преимущество isEqualToNumber: метод, или мы должны придерживаться integerValue, если значение для сравнения уже NSNumber?

Одно преимущество, которое я вижу, состоит в том, что если someVariable изменится с NSInteger на CGFloat, никакие изменения кода не потребуются для нового способа.

4 ответа

Решение

Новый способ действительно новый синтаксис вокруг старого

[myNumber isEqualToNumber:[NSNumber numberWithInt:5]]

который требует дополнительного вызова numberWithInt:; по сути, мы сравниваем решение с одной диспетчеризацией и нулевыми распределениями с решением с двумя диспетчеризацией и, возможно, распределением / освобождением.

Если вы сделаете это сравнение вне замкнутого цикла, это не будет иметь значения. Но если вы делаете это в очень узком цикле, возможно, когда рисуете что-то, вы можете увидеть замедление. Вот почему я останусь со старым методом

[myNumber integerValue] == 5

"Старый способ" - это один вызов метода плюс оператор сравнения с двумя основными типами.

"Новый путь" - это один вызов метода плюс создание дополнительного объекта.

Таким образом, старый способ более эффективен. Но если это не сделано в цикле высокой производительности (или что-то подобное), разница незначительна.

Как вы заявили, новый способ может быть более гибким в отношении конкретного типа номера.

Лично я бы выбрал форму, которую вы находите более удобочитаемой и понятной, если у вас нет четкой и конкретной проблемы с производительностью, с которой нужно иметь дело.

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

Короткий ответ: [myNumber integerValue] == 5 все еще лучше.

Длинный (но, вероятно, вам все равно) ответ: Начиная с iOS 5, "некоторые" номера NSN реализуются с помощью теговых указателей ( быстрый поиск в Google). Это означает, что пока значение NSNumber умещается в 24 бита (для 32-разрядных процессоров ARM iPhone / iPad), фактический экземпляр не будет создан. Таким образом, в теории, если вы уверены, что значения никогда не будут превышать 24 бит, вы можете просто сделать myNumber == @5,

Что не очень хороший совет. Придерживаться [myNumber integerValue] == 5, Помеченные указатели помогают программистам во время выполнения, а не для программистов.

NSNumber *yourNumber = @(5)

Используйте когда yourNumber никогда не должно быть ноль. это потерпит крах, когда yourNumber становится ноль

[myNumber isEqualToNumber:yourNumber] 

Используйте когда yourNumber может быть ноль

myNumber.integerValue == yourNumber.integerValue

обратите внимание, что вы должны знать о максимальном значении, которое может принимать yourNumber.

Если ваш номер будет превышать INT_MAX 2147483647использовать longValue или же longlongValue

Другие вопросы по тегам