ios - Do memory addresses follow a pattern in iOS?
问题描述
I'm comparing two NSNumbers in my app and I've done it the wrong way:
if(max < selected)
And it should be:
if([max longValue] < [selected longValue])
So the first comparison is really comparing the two object memory addresses, the funny thing (at least for me) is that the values seems to be related with the addresses. For example, if I get the first number with value 5
its memory address is 0xb000000000000053
and if I get the second with 10
is 0xb0000000000000a3
(being "a" equivalent to 10 in hexadecimal).
For that reason the first comparison (wrong) was actually working. Now an user complaint about an error here and is obviously because of this but it has lead me to the next questions:
Does this only happen in simulators? Cause it's where I'm testing, and the user will have a real device. Or maybe this happen normally but it's not a rule always fulfilled?
解决方案
This is a "tagged pointer," not an address. The value 5 is packed inside the pointer as you've seen. You can identify tagged pointers because they're odd (the last bit is 1). It's not possible to fetch odd addresses on any of Apple's hardware (the word size is 4 or 8 bytes), so that bit is never set for a real address.
Tagged pointers are only available on 64-bit platforms. If you run on a 32-bit platform then the values will be real pointers, and they may not be in any particular order, which will then lead to the kinds of bugs you're encountering. Unfortunately I don't believe there is any way to get a compiler warning or even a static analysis warning for this kind of misuse on NSNumber.
Mike Ash provides an in-depth discussion of the subject.
On a slightly related note, on 32-bit platforms, certain NSNumbers are singletons, particularly small values since they're used a lot (-1 through 12 as I recall, but I believe it's different on different platforms). This means that ==
may happen to work for some numbers, but not for others. It also means that without ARC, it was possible to over-release a specific value (for example, 4) such that your program would crash the next time it happened to use that value. True story.... very hard to debug.
推荐阅读
- typescript - 如果测试用例并行运行,如何在量角器中创建报告?
- c# - 如何让角色转向相机的方向?[Unity3D]
- python - 当我通过 python 中的文件对话框打开图像时,为什么会收到“UnicodeDecodeError”?
- javascript - 在 JavaScript 中创建迭代器时,数组未传递给 next() 方法
- android - 错误警告:应避免使用 flatDirs,因为它不支持任何元数据格式
- typescript - 如何在界面中定义一个“typeof this”的类型
- python - 在 python NameError 中定义异常错误
- python - 在单元测试 Python 中模拟
- swift - [标签比较:]:无法识别的选择器发送到实例
- swift - 如何在进入屏幕时自动刷新视图控制器中的表格视图?