Objective c 苹果的模板是否包含一个bug,因为它们被强制转换为BOOL?

Objective c 苹果的模板是否包含一个bug,因为它们被强制转换为BOOL?,objective-c,cocoa-touch,cocoa,boolean,null,Objective C,Cocoa Touch,Cocoa,Boolean,Null,根据数据显示,由于指针大于布尔值,布尔值的转换可能有6%的时间失败。因此,他建议,如果要检查对象是否存在,则应检查nil if (self != nil) { 而不是苹果模板所做的 if (self) { 苹果的模板是否包含bug,或者是否有其他我不知道的语法糖 自从他们投到布尔 不,他们没有。根本没有演员阵容。但是,表达式的计算是作为逻辑值的。对于指针(它们是nil和self),NULL指针的计算结果为false,其他任何值都为true。这不是一个bug,只是一种简写方式,它是完全有效的C

根据数据显示,由于指针大于布尔值,布尔值的转换可能有6%的时间失败。因此,他建议,如果要检查对象是否存在,则应检查nil

if (self != nil) {
而不是苹果模板所做的

if (self) {
苹果的模板是否包含bug,或者是否有其他我不知道的语法糖

自从他们投到布尔

不,他们没有。根本没有演员阵容。但是,表达式的计算是作为逻辑值的。对于指针(它们是
nil
self
),
NULL
指针的计算结果为false,其他任何值都为true。这不是一个bug,只是一种简写方式,它是完全有效的C


关于为什么要对
NULL
nil
执行显式比较:在某些情况下,它可能更具可读性,尤其是当对表达式的类型和范围一目了然时。然而,在Objective-C和Cocoa中,这是构造函数中的常见习惯用法,任何有经验的程序员都会毫无问题地掌握它。

不,如果指针不是零,这不会失败,它是安全的,唯一的区别是语法,我不推荐这样或那样的方法,因为它们是相同的。
你不是在把self投射到BOOL,你只是在检查self是否与零不同。

编辑
根据Martin的评论,我记录了错误的调试消息。 都一样

这里有一个简单的测试

NSString *str = nil;
// suppose our string points to a string object whose starting address is 0x4500
//I'm assigning it manually so that I can test
str = 0x4500;
NSLog(@"%d",str);
if (str) {
    NSLog(@"It's non-nil");
}
else {
    NSLog(@"It's nil");
}

if (str == nil) {
    NSLog(@"It's nil");
}
else {
    NSLog(@"It's non-nil");
}
输出为:

It's non-nil
It's non-nil

Objective-C是基于C的,在C中,
if
语句没有对布尔值进行运算,这可能令人惊讶

C具有类型的层次结构:

  • char
    、整数和枚举(
    enum
    )类型是整数类型
  • float
    double
    longdouble
    是真正的浮动类型
  • 有三种复数类型,它们与实浮点类型一起被简单地称为浮点类型
  • 整数类型和浮点类型组合形成算术类型
  • 算术类型和指针类型构成标量类型

现在来看
if
语句,它是以下形式之一:

if ( expression ) statement
if ( expression ) statement else statement
其中表达式必须是任何标量类型。如果表达式的比较结果不等于0,则执行第一条(或唯一一条)语句;如果表达式的比较结果等于0,则执行第二条(如果存在)语句

因此:

结果相同

第一个表达式
self
是某种指针类型,它是一种标量类型,并被比较为不等于指针类型的零(在代码中由
nil
表示)。第二个表达式
self!=nil
是一个等式表达式,它产生
0
1
类型
int
,这也是一个标量类型

因此,从技术上讲,第二种形式涉及中间生成
int
值,但没有编译器会实际生成一个值(当然,除非您将表达式的结果指定给变量)

注:

  • 有点奇怪
    如果(sin(角度))…
    是有效的
  • switch
    语句对整数类型而不是标量类型进行操作

  • HTH

    @0x7fffffff谢谢!:D哦,至少你可以在必要的时候继续修改我的英语(碰巧:P)我不会太担心你的英语。我住在美国,很明显,在我们这个年龄段的很多人已经决定,屠杀英语应该是一种趋势。我只是说,你说的英语比我知道的许多英语母语的人好。“0x7FFFFFFF听上去很好,实际上:”考虑到法语拼写和眼动学大体相同,我应该考虑在语言中获得一个硕士学位,而不是在CS中……别担心,在我的国家匈牙利,同样的现象也存在,主要是在年轻人中——我一直在努力不让自己落入这个“愚蠢的青少年”的行列。@SteveMoser为什么会有所不同呢?请那些来自爪哇和类似背景的人注意。在Java等语言中,无法计算非布尔表达式。如果(my_integer)和
    如果(this)
    仅当(0!=my_integer)和
    如果(null!=this)
    在那里有效,Java将不接受
    。最好清楚地说明在C(和目标C)中,表达式是在严格的规则下计算的,但没有任何强制转换。这可能会失败,请参阅Inder的答案。@H2CO3这与我的编辑相同。我记录错误了debug mesageInders的答案不能证明如果(self)
    可能失败,请查看我对该答案的评论。我的答案是对的,可能你误解了。所以我编辑了我的答案并进入了学究模式。Daij-Djan:对不起,我不是有意打扰,仅仅是
    1+
    部分就让它有点晦涩难懂。迈克·阿什的帖子实际上并没有谈论
    if
    ,而是把
    BOOL
    放在一起。他们在不同的部分,讨论不同的陷阱:第一个关于
    if
    ,是关于链式比较的,比如
    0你的第一个测试是错误的:
    if(str){NSLog(@“It's nil”);}…
    没有意义,应该是
    if(str){NSLog(@“It's non nil”);}…
    !!然后您会看到
    if(str)
    if(str!=nil)
    总是有相同的结果。@H2CO3我记录了错误的输出。现在编辑了我的答案,正如你所期望的anser@InderKumarRathore我之前的评论中没有讽刺。谢谢你指出这是如何被打破的。@Martinar谢谢你的接球。另一方面,从那以后我一直在寻找这个问题。现在我松了一口气,苹果正在做正确的事情:)。因此,上述blo
    if (self) ...
    
    if (self != nil) ...