通过BOOLselectbutton组

有人可以教育我为什么以下不起作用? 该button从不被设置为选中状态。

[self.boldButton setSelected:isBold]; 

如果我用if else语句replace上面,它工作正常。 我也可以改变setSelected值为1或0,而不是YES或NO,它仍然正常工作。

 if (isBold) { [self.boldButton setSelected:YES]; } else { [self.boldButton setSelected:NO]; } 

所以我有一个工作项目,但我不明白为什么这两个实现不能提供相同的结果。 谢谢。

FWIW – 我用另一种方法进行粗体testing。 虽然如果testing是有缺陷的,我不明白第二种方法是可行的,而第一种方法不行。

 - (BOOL)isBold { CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self); CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef); return (symbolicTraits & kCTFontTraitBold); } 

BOOL<objc/objc.h>是这样定义的:

 typedef signed char BOOL; 

这意味着BOOL实际上可以在-128到127(含)范围内保存任何值。

-[UIControl setSelected:]工作原理大致如下:

 #define kSelectedBitPosition 10 #define kSelectedBit (1 << kSelectedBitPosition) - (void)setSelected:(BOOL)selected { if (((self->_controlFlags >> kSelectedBitPosition) & 1) == selected) { return; } else { self->_controlFlags = (self->_controlFlags & ~kSelectedBit) | ((selected & 1) << kSelectedBitPosition); [self setNeedsDisplay]; } } 

(我用Hopper反汇编了UIKit的模拟器版本来弄清楚。)

所以,注意两点:

  • 如果selected == 0selected == 1if语句条件只能为true。 如果selected有任何其他值,将永远不会是真实的。

  • 赋值语句(更新_controlFlags )只使用selected位0(1的位)。 因此,例如,如果selected == -2 ,这在C中逻辑上为真,并且除了位0都设置了每个位,赋值语句仍然不会打开_controlFlags的位。

这意味着您必须将0或1传递-[UIControl setSelected:] 。 没有其他价值可靠地工作。

在C中将所有非零值转换为1的最短方法是通过应用! 操作符两次:

 [self.boldButton setSelected:!!isBold]; 

但是,修复-isBold方法返回一个“安全” BOOL可能更好:

 - (BOOL)isBold { CTFontRef fontRef = (CTFontRef)CFBridgingRetain(self); CTFontSymbolicTraits symbolicTraits = CTFontGetSymbolicTraits(fontRef); return !!(symbolicTraits & kCTFontTraitBold); }