Objective c 当使用显式块返回类型求反时,为什么BOOL变为int

Objective c 当使用显式块返回类型求反时,为什么BOOL变为int,objective-c,Objective C,为什么BOOL是typedef有符号字符,在求反时会转换为int // Doesn't compile. NSInteger occurrences = [[contactCountries indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) { return ![obj isEqualIgnoringCase:@"astring"]; }] count]; 错误: 当块文字具有未指定的显式返回类型时,返回

为什么
BOOL
typedef有符号字符
,在求反时会转换为
int

// Doesn't compile.
NSInteger occurrences = [[contactCountries indexesOfObjectsPassingTest:^(id obj, NSUInteger idx, BOOL *stop) {
    return ![obj isEqualIgnoringCase:@"astring"];
}] count];
错误:

当块文字具有未指定的显式返回类型时,返回类型“int”必须与以前的返回类型“BOOL”(又名“signed char”)匹配

这是由于Objective-C中的“C”造成的。C99是关于
操作员(强调我的):

6.5.3.3一元算术运算符,第5段:

逻辑求反运算符的结果!如果其操作数的值比较不等于0,则为0;如果其操作数的值比较等于0,则为1结果具有int类型。表达式!E等于(0==E)

简单地说:

return (BOOL)![obj isEqualIgnoringCase:@"astring"];

正确,但更好的解决方案是显式指定块返回类型:
indexesOfObjectsPassingTest:^BOOL(id obj,NSUInteger idx,BOOL*stop){…
,而不是计算返回值。@Martin:是的,我就是这样解决的。我只是对发生这种情况的原因感兴趣。@Martin:是的,那确实更好。@DarkDust,在阅读了你的答案后,我明白了!的结果总是0或1,我是对的?@Jageen,问题不是
BOOL
int。这是块类型之间的不匹配。当定义块时没有显式返回类型,编译器通过检查块中的
return
语句和返回表达式的类型来派生类型。因此,问题中的块类型是
int(^)(id obj,NSUInteger idx,BOOL*stop)
-indexesOfObjectsPassingTest:
方法需要类型为
BOOL(^)(id obj,nsu整数idx,BOOL*stop)的块