[英]typecast BOOL always returns false in iOS 8.1.1
I save & retrive the BOOL value in a dictionary using the following methods. 我使用以下方法将BOOL值保存并检索到字典中。
[userData setObject:@YES forKey:@"IS_AGENT"];
(BOOL) [userData objectForKey:@"IS_AGENT"];
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值时,在以下具有iOS 8.1.1的设备iPhone5s,iPhone5c,iPhone6,iPhone6 +上,我总是会出错,而在具有相同iOS 8.1.1的iPod Touch中,相同的代码也可以正常工作
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." 谷歌搜索后,我知道我们不应该这样输入强制转换
BOOL
因为“ BOOL
是一个char
,它是8位。如果您尝试通过BOOL
压缩一个大于char
的值,编译器会很高兴地截断高位,切掉它们。”
Now I fixed the issue simply sending boolValue
message to a particular object. 现在,我解决了仅将
boolValue
消息发送到特定对象的问题。 Check the working code below. 检查下面的工作代码。
[[userData objectForKey:@"IS_AGENT"] boolValue];
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?" 好的,我的问题是:“为什么仅在特定设备(iPhone5s,iPhone5c,iPhone5,iPhone6 +)上而不是在具有相同iOS 8.1.1的iPod touch中发生这种情况?”
Here's my speculation what happened before iOS 8.1.1. 这是我的猜测,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.
也许Apple改变了这里标记的指针的工作方式,但我还没有机会对其进行测试,也没有找到关于Apple是否在此系统中进行了某些更改的参考。
You were casting a pointer to a BOOL. 您正在将指针投射到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 . 由于我们在这里讨论的是小端字节系统,因此将像0x12345678这样的指针强制转换为
char
产生0x78,当强制转换为BOOL
,由于字节不为0,因此会得到1。在具有64位二进制文件的64位iOS系统上,运行时使用标记的指针 。
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.
如果将该字节强制转换为BOOL,您将始终获得1 / YES。
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). 但是对于未标记的指针,由于对齐,最后四位始终为0。并且偶然地,它的其他位也为0(在我的测试中,我仅看到0x20的倍数,因此每8位对象将具有0x00)。 When you cast that to a
BOOL
you'll get YES most of the time and sometimes NO. 当您将其转换为
BOOL
时,大多数情况下会得到YES,有时会得到NO。
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. 如您
[userData[@"IS_AGENT"] boolValue]
如果您的部署目标是iOS> = 6,则查询值的正确方法是[[userData objectForKey:@"IS_AGENT"] boolValue]
或简单地[userData[@"IS_AGENT"] boolValue]
。
First of all you are using setValue:forKey:
and valueForKey:
that are KVC methods, 首先,您使用的是KVC方法
setValue:forKey:
和valueForKey:
,
This is strong mistake. 这是一个严重的错误。
You need to use setObject:forKey:
and objectForKey:
to write/read objects from NSMutableDictionary
. 您需要使用
setObject:forKey:
和objectForKey:
从NSMutableDictionary
写入/读取对象。
Also you are casting NSNumber
to BOOL
, which will have unexpected behavior. 另外,您正在将
NSNumber
强制转换为BOOL
,这将产生意外行为。
Instead of that code, use 代替该代码,使用
[userData setObject:@YES forKey:@"IS_AGENT"];
BOOL isAgent = [[userData objectForKey:@"IS_AGENT"] boolValue];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.