Адреса памяти соответствуют шаблону в iOS? - PullRequest
0 голосов
/ 25 октября 2019

Я сравниваю два номера NSN в моем приложении, и я сделал это неправильно:

if(max < selected)

И это должно быть:

if([max longValue] < [selected longValue])

Итак, первое сравнениеНа самом деле, сравнивая два адреса памяти объектов, забавно (по крайней мере, для меня) то, что значения, похоже, связаны с адресами. Например, если я получу первое число со значением 5, его адрес памяти будет 0xb000000000000053, а если я получу второе с 10, это будет 0xb0000000000000a3 (будучи "a" эквивалентно 10 в шестнадцатеричном формате).

По этой причине первое сравнение (неправильное) действительно работало. Теперь пользователь жалуется на ошибку здесь и, очевидно, из-за этого, но это привело меня к следующим вопросам:

Это происходит только в симуляторах? Потому что именно там я тестирую, и у пользователя будет настоящее устройство. Или, может быть, это происходит нормально, но это правило не всегда выполняется?

1 Ответ

3 голосов
/ 25 октября 2019

Это «теговый указатель», а не адрес. Значение 5 упаковано внутри указателя, как вы видели. Вы можете идентифицировать теговые указатели, потому что они нечетные (последний бит равен 1). Невозможно получить нечетные адреса на любом оборудовании Apple (размер слова 4 или 8 байт), поэтому бит для реального адреса никогда не устанавливается.

Помеченные указатели доступны только на 64-битных платформах,Если вы работаете на 32-битной платформе, то значения будут реальными указателями, и они могут быть не в каком-то определенном порядке, что приведет к типам ошибок, с которыми вы сталкиваетесь. К сожалению, я не верю, что есть какой-либо способ получить предупреждение компилятора или даже предупреждение статического анализа для такого рода неправильного использования в NSNumber.

Майк Эш обеспечивает всестороннее обсуждение предмета.

На слегка связанной ноте, на 32-битных платформах, определенные номера NSN являются синглетонами, особенно небольшими значениями, так как они используются часто (от 1 до 12, насколько я помню, но я считаю, что это другоена разных платформах). Это означает, что == может работать для некоторых чисел, но не для других. Это также означает, что без ARC можно было перевыпустить определенное значение (например, 4), так что ваша программа потерпела крах в следующий раз, когда ей случится использовать это значение. Правдивая история .... очень трудно отлаживать.

...