当我用BOOL表示32位时,我得到:

BOOL b1=8960; //b1 == NO

bool b2=8960; //b2 == true  

但对于64位,我得到:

BOOL b1=8960; //b1 == YES

bool b2=8960; //b2 == true

BOOL从32位到64位的变化是什么?

推荐答案

@虽然这是对的,但它不能解释为什么...

BOOL b1=8960; //b1 == NO

... 在32位iOS上计算为NO,以及为什么在64位iOS上计算为YES.让我们从头开始.

ObjC BOOL definition

#if (TARGET_OS_IPHONE && __LP64__)  ||  (__ARM_ARCH_7K__ >= 2)
#define OBJC_BOOL_IS_BOOL 1
typedef bool BOOL;
#else
#define OBJC_BOOL_IS_CHAR 1
typedef signed char BOOL; 
// BOOL is explicitly signed so @encode(BOOL) == "c" rather than "C" 
// even if -funsigned-char is used.
#endif

对于64位iOS或ARMv7k(手表),它被定义为bool,其余的定义为signed char.

ObjC BOOL YES and NO

阅读Objective-C Literals,你可以找到:

以前,BOOL类型只是signed char的typedef,而

#if __has_feature(objc_bool)
#define YES __objc_yes
#define NO  __objc_no
#else
#define YES ((BOOL)1)
#define NO  ((BOOL)0)
#endif

编译器隐式地将__objc_yes__objc_no转换为(BOOL)1

bool definition

boolstdbool.h中定义的宏,它扩展为_Bool,这是C99中引入的布尔类型.它可以存储两个值,01.没别的了.更准确地说,stdbool.h定义了四个要使用的宏:

/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool, bool, false, true as a GNU extension. */
#define _Bool bool
#define bool  bool
#define false false
#define true  true
#endif

#define __bool_true_false_are_defined 1

_Bool

C99中引入了_Bool,它可以保存01的值.重要的是:

当一个值降级为_Bool时,如果该值

现在我们知道这mess个来自哪里,我们可以更好地理解发生了什么.

64-bit iOS || ARMv7k

BOOL -> bool -> _Bool (values 0 or 1)

8960降到_Bool得到1,因为该值不等于0.见第_Bool节.

32-bit iOS

BOOL -> signed char (values -128 to 127).

如果将int个值(-128127)存储为signed char,则每C99 6.3.1.3个值不变.否则为implementation defined(C99报价):

否则,新类型将被签名,并且无法表示该值

It means that clang can decide. To make it short, with the default settings, clang wraps it around (int -> signed char):

  • -129变成127
  • -130变成126
  • -131变成125
  • ...

相反的方向:

  • 128变成-128
  • 129变成-127
  • 130变成-126
  • ...

但因为signed char可以存储-128127之间的值,所以它也可以存储0.例如,256(int)变成0(signed char).当你的价值被包裹起来...

  • 8960变成0
  • 8961变成1
  • 8959变成-1
  • ...

... 当存储在signed char中时,它变为0(89602568960 % 256 == 0的倍数),因此它是NO.这同样适用于256512...256的倍数.

我强烈建议使用YESNOBOOL,不要依赖像int这样的花哨C特性作为if中的条件,这就是为什么Swift有Booltruefalse,而在预期的条件下不能使用Int值.只是为了避免这种情况...

Objective-c相关问答推荐

UICollectionView:一行或一列

UIAlertController:supportedInterfaceOrientations 被递归调用

协议与类别

如何在运行时向对象添加属性?

自动属性合成 (@property) 和继承

在 viewDidAppear 之前无法正确设置框架

我可以以编程方式滚动到 UIPickerView 中所需的行吗?

指向方法返回类型的Expected a type错误

Container View 好像有 UINavigationBar 一样被下推?

将 NSArray 转换为 NSDictionary

Crashlytics iOS - 记录捕获的异常

使用情节提要的条件转场

无法加载从笔尖引用的图像

Apple 的 API 中的k前缀表示什么?

类在两者中都实现.将使用两者之一

如何保存我的 iPhone 应用程序的用户首选项?

Objective-C 中的 super 到底是什么?

如何在 ios 8 的 alertview 中添加文本输入?

如何减小使用 UIImagePickerController 创建的视频的文件大小?

Xcode - 如何将 XIB 连接到 ViewController 类