对 UITextView、UIButton 和 BOOL 感到困惑

Confused about UITextView, UIButton and BOOL

我有一个 textView 和一个按钮。 Button的enabled属性与textView中的文本长度有关。我直接把NSUInteger赋值给BOOL,现在证明不合适

- (void)textViewDidChange:(UITextView *)textView {
    self.button.enabled = textView.text.length; //unsuitable on 32-bit. Should be `textView.text.length > 0`
}

32 位设备上的奇怪之处:如果我将 "abc" 粘贴到 textView,或粘贴 "ab" 然后键入 "c",该按钮始终处于禁用状态。但是,如果我将这三个字母一一键入,该按钮将按其应有的方式执行。 3种情况都达到了self.button.enabled = (BOOL)3,但是为什么按钮的表现不一样呢?

BOOL 类型

不同的行为实际上与设备的架构有关。 iOS SDK 为 32 位和 64 位架构定义 BOOL 的方式有所不同。请参阅 objc.h 中的这段摘录:

#if !defined(OBJC_HIDE_64) && TARGET_OS_IPHONE && __LP64__
typedef bool BOOL;
#else
typedef signed char BOOL; 
#endif

所以 BOOL 在 32 位上可以有 0 到 255 之间的任何值,而在 64 位上它被编译器强制只有值 0 或 1。你可以通过 [=41= 轻松地尝试这个] 模拟器上的下面这行,设置为iPhone4s(32位)或者iPhone6(64位)。

NSLog(@"%d", (BOOL)2);

这就是您在不同设备上看到不同行为的原因。

编辑: Post OP 评论:

要理解这一点,您需要了解 enabled 属性 是如何规定的:unsigned int enabled:1。这定义了宽度为 1 的位域。

32 bit 系统上,根据 C 标准,当分配一个更大宽度的无符号整数时,剩余的位将被丢弃。所以最低位是实际驱动按钮 enabling/disabling 的位。