问题描述
我保存&使用以下方法检索字典中的 BOOL 值.
I save & retrive the BOOL value in a dictionary using the following methods.
[userData setObject:@YES forKey:@"IS_AGENT"];
(BOOL) [userData objectForKey:@"IS_AGENT"];
在上面的代码中,在重试字典中的 bool 值时,我在以下设备 iPhone5s、iPhone5c、iPhone6、iPhone6+ 中总是出错,它们具有 iOS 8.1.1 并且相同的代码在具有相同 iOS 的 iPod Touch 中工作正常8.1.1
In the above code while retrying the bool value from the dictionary I always get false in the following devices iPhone5s, iPhone5c, iPhone6, iPhone6+ which has iOS 8.1.1 and the same code works fine in iPod Touch which has the same iOS 8.1.1
在谷歌搜索之后我开始知道我们不应该像这样输入 BOOL
因为BOOL
是一个 char
,它是八位. 如果您尝试通过 BOOL
压缩一个大于 char
的值,编译器会很乐意截断高位,将它们切掉."
After googled I came to know that we should not type cast BOOL
like this because "BOOL
is a char
, which is eight bits. If you try to squeeze a value larger than a char
through BOOL
, the compiler will happily truncate the upper bits, slicing them off."
现在我解决了这个问题,只需将 boolValue
消息发送到特定对象.检查下面的工作代码.
Now I fixed the issue simply sending boolValue
message to a particular object. Check the working code below.
[[userData objectForKey:@"IS_AGENT"] boolValue];
好的.我的问题是为什么它只在特定设备(iPhone5s、iPhone5c、iPhone5、iPhone6+)中发生,而不是在具有相同 iOS 8.1.1 的 iPod touch 中发生?"
Ok fine.My question is "Why is it happening in a particular devices (iPhone5s,iPhone5c,iPhone5,iPhone6+) only and not in iPod touch which is having the same iOS 8.1.1?"
推荐答案
以下是我对 iOS 8.1.1 之前的推测.也许苹果改变了标记指针在这里的工作方式,我还没有机会测试它,也没有找到任何参考苹果是否确实改变了这个系统中的某些东西.
Here's my speculation what happened before iOS 8.1.1. Maybe Apple changed the way tagged pointers work here, I haven't had an opportunity to test it yet and haven't found any references whether Apple did change something in this system.
您正在将指针投射到 BOOL.由于我们在这里讨论的是小端系统,因此将像 0x12345678 这样的指针转换为 char
会产生 0x78,当您转换为 BOOL
时,您会得到 1,因为字节不是 0.在具有 64 位二进制文件的 64 位 iOS 系统上,运行时使用 标记指针.
You were casting a pointer to a BOOL. Since we're talking about little endian systems here, a pointer like 0x12345678 casted to char
yields 0x78, when you cast to BOOL
you get 1 since the byte is not 0. On 64-bit iOS systems with 64-bit binaries, the runtime uses tagged pointers.
对于标记指针,第一个字节(最低有效数字,我们是小端)将始终设置最后一位以将其标记为标记指针.如果您将该字节转换为 BOOL,您将始终得到 1/YES.
For tagged pointers, the first byte (which are the least significant digits, we're little endian) will always have the last bit set to mark it as a tagged pointer. If you cast that byte to BOOL you'll always get 1/YES.
但是对于未标记的指针,由于对齐,最后四位始终为 0.偶然地,其他位也为 0(在我的测试中我只看到 0x20 的倍数)所以每 8 个对象都会有 0x00).当您将其转换为 BOOL
时,大多数情况下您会得到 YES,有时会得到 NO.
But for non-tagged pointers, due to aligning, the last four bits are always 0. And by chance it can happen that the other bits of that are are 0 too (in my tests I've only seen multiples of 0x20 so every 8th object would have 0x00). When you cast that to a BOOL
you'll get YES most of the time and sometimes NO.
正如您已经发现的,查询值的正确方法是 [[userData objectForKey:@"IS_AGENT"] boolValue]
或简单地 [userData[@"IS_AGENT"] boolValue]
如果您的部署目标是 iOS >= 6.
As you already found out, the correct way to query the value is [[userData objectForKey:@"IS_AGENT"] boolValue]
or simply [userData[@"IS_AGENT"] boolValue]
if your deployment target is iOS >= 6.
这篇关于typecast BOOL 在 iOS 8.1.1 中总是返回 false的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!