1

有人可以告诉我为什么以下方法不起作用吗?该按钮永远不会被设置为选中。

[self.boldButton setSelected:isBold];

如果我用 if else 语句替换上面的内容,它就可以正常工作。我还可以将 setSelected 值更改为 1 或 0,而不是 YES 或 NO,它仍然可以正常工作。

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

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

FWIW - 我用另一种方法测试粗体。虽然如果测试有缺陷,我看不出第二种方法如何工作,而第一种方法仍然没有。

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

1 回答 1

15

BOOL定义如下<objc/objc.h>

typedef signed char     BOOL;

这意味着 aBOOL实际上可以保存 -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];
    }
}

(我UIKitHopper反汇编了模拟器版本来解决这个问题。)

所以,注意两点:

  • if语句条件只有在或selected == 0时才能为真selected == 1selected如果有任何其他价值,它永远不会是真的。

  • 赋值语句(更新_controlFlags)仅使用 的位 0(1 的位)selected。因此,例如,如果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);
}
于 2012-12-06T19:14:48.117 回答