在iOS 8.1.1中,typecast BOOL始终返回false

时间:2014-11-20 07:54:11

标签: ios objective-c iphone casting arm64

我救了&使用以下方法检索字典中的BOOL值。

[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

在谷歌搜索后,我发现我们不应该像这样输入演员BOOL因为" BOOLchar,这是8位。如果您尝试通过char挤压大于BOOL的值,编译器将很乐意截断高位,将它们切掉。"

现在我修复了问题,只需将boolValue消息发送到特定对象即可。检查下面的工作代码。

[[userData objectForKey:@"IS_AGENT"] boolValue];

好的。我的问题是"为什么它只在特定设备(iPhone5s,iPhone5c,iPhone5,iPhone6 +)中发生而不是在具有相同iOS 8.1.1的iPod touch中发生?"

2 个答案:

答案 0 :(得分:3)

以下是我对iOS 8.1.1之前发生的事情的猜测。也许Apple改变了标记指针的工作方式,我还没有机会对它进行测试,并且没有找到任何关于Apple是否确实改变了这个系统的内容的参考。

您正在向BOOL投射指针。由于我们在这里谈论小端系统,像0x12345678这样的指针转换为char会产生0x78,当你转换为BOOL时,由于字节不是0,你得到1。在64位上具有64位二进制文​​件的iOS系统,运行时使用tagged pointers

对于标记指针,第一个字节(最低有效数字,我们是小端)将始终设置最后一位以将其标记为标记指针。如果将该字节转换为BOOL,则总是得到1 / YES。

但对于非标记指针,由于对齐,最后四位始终为0.并且偶然会发生其他位也为0(在我的测试中我只看到了倍数)为0x20所以每第8个对象都有0x00)。当你把它投射到BOOL时,你大部分时间都会得到YES,有时候会没有。

正如您已经发现的那样,如果您的部署目标是iOS> = 6,则查询该值的正确方法为[[userData objectForKey:@"IS_AGENT"] boolValue]或仅[userData[@"IS_AGENT"] boolValue]

答案 1 :(得分:1)

首先,您使用的是setValue:forKey:valueForKey: KVC方法,
这是一个很大的错误。

您需要使用setObject:forKey:objectForKey:来编写/读取NSMutableDictionary中的对象。
此外,您将NSNumber投射到BOOL,这会产生意外行为。

使用

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