MelonTeam 移动终端前沿技术的探索者

易踩的坑:32&64bit架构下BOOL类型不同

2017-09-29
dalei
ios

起因

之前接到一个关于某UI控件在部分机型上无法正常显示的bug单,定位至此:

发现是由于这行语句在部分机型上无法将UI控件的hidden属性置为NO。

此外,控件在iphone5上不可见,在iphone5s及以上机型中均可正常显示。

思路

首先,iPhone 5是32位架构,苹果从iPhone 5s开始对全线移动产品使用64位架构。

其次,performSelector: withObject:要求所传参数为对象。

因此初步判断,这是在32、64位操作系统中,NSNumber与BOOL类型之间转换结果不同导致的。

验证

验证结果的确如此。

在iphone5s(64位架构)上,将由NO初始而来的NSNumber赋予BOOL变量,得到的仍为NO:

但在iphone5(32位架构)上,结果却既非YES也非NO

探寻

究其原因,32-bit下,@encode(BOOL)返回’c’

而在64-bit下,@encode(BOOL)返回’B’

根据苹果官方文档:

由上可知,32-bit下,BOOL被定义为signed char;64-bit下,BOOL被定义为bool。

因此,32-bit版本的BOOL包括了256个值的可能性,而64-bit下只有0(NO),1(YES)两种可能,是真正意义上的Boolean类型。

结论

通过performSelector等方式调用系统API时,若参数为BOOL,不可直接传由BOOL值初始而来的NSNumber(除非APP已不需要支持iphone5及其以下的机型)。

可调用自定义函数来实现相同的功能,比如此例中的修改方式便为:


说一说

目录