typecast BOOL always returns false in iOS 8.1.1

让人想犯罪 __ 提交于 2019-12-11 07:56:36

问题


I save & retrive the BOOL value in a dictionary using the following methods.

[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

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."

Now I fixed the issue simply sending boolValue message to a particular object. 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?"


回答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.

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.

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.

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.

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.




回答2:


First of all you are using setValue:forKey: and valueForKey: that are KVC methods,
This is strong mistake.

You need to use setObject:forKey: and objectForKey: to write/read objects from NSMutableDictionary.
Also you are casting NSNumber to BOOL, which will have unexpected behavior.

Instead of that code, use

    [userData setObject:@YES forKey:@"IS_AGENT"];
    BOOL isAgent = [[userData objectForKey:@"IS_AGENT"] boolValue];


来源:https://stackoverflow.com/questions/27034426/typecast-bool-always-returns-false-in-ios-8-1-1

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!