Равенство примитивного значения 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