如何将@NO 和@YES 与优雅进行比较并且没有误报/否定的风险?

Posted

技术标签:

【中文标题】如何将@NO 和@YES 与优雅进行比较并且没有误报/否定的风险?【英文标题】:How to compare @NO and @YES with elegance and without risk of false positives/negatives? 【发布时间】:2013-03-14 11:16:32 【问题描述】:

我想使用类似的布尔字面量

if (condition == @NO) 


else if (condition == @YES) 


当我尝试这个时,XCode 希望我使用 NSNumber 方法进行比较,例如 isEqualTo。有没有更简单的方法来做到这一点(没有 isEqualTo)?如果不能,我应该使用 isEqualTo、isEqualToValue 还是 isEqualToNumber?

【问题讨论】:

【参考方案1】:

您可以将@NO 保存在字典中,因为@NO 是一个对象。您不能将 NO 保存在字典中。 所以在需要时使用@NO.boolValue。例如:

NSDictionary *userSetting = (NSDictionary *)[[NSUserDefaults standardUserDefaults] objectForKey:@"user"];
//Suppose you have done: userSetting[@"canWriteCode"] = @YES;
if ([userSetting[@"canWriteCode"] boolValue])
    [self helloProgrammer];

【讨论】:

【参考方案2】:

假设condition的数据类型是BOOL,那么你想要:

if (condition) 
    // true (YES)
 else 
    // false (NO)

如果条件是NSNumber,则使用:

if ([condition boolValue]) 
    // true (YES)
 else 
    // false (NO)

如果condition 是基于一些任意数字,则将0 视为NO 并将非零视为YES

同样,如果 conditionNSNumber,那么:

if ([condition intValue]) 
    // non-zero - true (YES)
 else 
    // zero - false (NO)

更新:基于 OP 的以下评论:

Condition 是一个布尔值,例如 if (myView.frame.size.height == 30)

这意味着实际问题想要进行如下检查:

if ((myView.frame.size.height == 30) == YES)

这很不寻常。正确的做法是:

if (myView.frame.size.height == 30) 
    // true - height is 30
 else 
    // false - height is not 30

无需担心误报或误报。条件要么为真,要么不为真。没有第三种可能。如果条件给出了错误的结果,那么解决方案是修复条件。

【讨论】:

哪些数字触发@NO 或@YES? 无直接。如果condition 是从[NSNumber numberWithBool:] 创建的,那么您将与@YES@NO 进行比较。 YES 相比,some cases 可能存在问题。 +1 表示不使用点语法进行非属性方法调用。 @yourfriendzak 注意所有选项。这是因为你没有说清楚。 condition 是什么类型的?你是如何创造它的价值的? @CarlVeazey 是的,在我们获得有关condition 类型及其值如何设置的更多详细信息之前,很难确定正确的解决方案。【参考方案3】:

您可以使用@YES.boolValue@NO.boolValue

因此,要与 bool 文字进行比较,您可以编写类似的内容(鉴于 conditionBOOL

if (condition == @NO.boolValue) 
  // Do something

【讨论】:

我不知道为什么这被否决了。如果conditionNSNumber 并且OP 不想使用isEqual:,那么这实际上是一种可能的解决方案。 你为什么会说@NO.boolValue而不是说NO > 我想使用 bool 字面量 @KevinBallard 我个人不会,但它是有效的。 @maddy 有效,是的,但就像将 NO 转换为字符串“nooohoooo”并将该字符串解析回 BOOL 一样毫无意义,对吧?【参考方案4】:

condition 是什么?是BOOL 还是NSNumber


如果conditionBOOL,那么您根本不想使用@NO@YES。你想说

if (condition) // test if condition is true

if (!condition) // test if condition is false

if (condition == NO) // same as previous, based on personal preference

注意千万不要说

if (condition == YES)

因为BOOL 实际上并不局限于01 作为值,它可以在char 中保存任何内容,所以如果condition 意外保存,例如3,那么if (condition)if (condition == YES) 的行为会有所不同。


如果conditionNSNumber,那么您仍然不想使用@NO@YES。您只想使用-boolValue 将其转换为BOOL,如

if ([condition boolValue]) // test if condition is true

if (![condition boolValue]) // test if condition is false

if ([condition boolValue] == NO) // same as previous, based on personal preference

这里的基本要点是,不要使用 @NO@YES 文字进行比较。这是没有意义的,也不优雅,因为你能用它们做的就是将它们转换回BOOLs。

【讨论】:

请注意 !condition 和 condition == NO 相同。有一种边缘情况。假设条件是 256。这将溢出到 0 并等于NO,因为它只是一个带符号的字符。但是,! 运算符返回一个 C 布尔值,C 标准明确定义它对除零以外的所有值都为真。所以BOOL 将是NObool 将是true 没关系,上面的例子似乎可以自己工作。咬我的情况略有不同。对于某些 BOOL 情况(即 8 位溢出),(flag) 和 (flag == NO) 都会为 false。 您也可以使用 Objective-C 2.0 表示法作为 boolValue 的访问器 @borrrden: !flagflag == NO 在定义上是相同的。 @KevinBallard 是的,你是对的,很抱歉我写了那个,但我之前遇到过 BOOL 问题,我认为它是相关的,但事实并非如此。我遇到麻烦的情况是,当我期望 YES 值(对于 bool 它将正常工作)但我得到了 NO 值。解决方案是要么转换为bool,要么使用!!condition(双重非运算符,隐式转换为bool)。我以为肯定会与此有关,但事实证明并非如此。【参考方案5】:

conditionNSNumber 吗?如果是这样,请使用:

if(condition.integerValue) 
    //condition is YES
 else 
    //condition is NO

顺便说一句,0代表NO,其他任何值都是YES;

【讨论】:

以上是关于如何将@NO 和@YES 与优雅进行比较并且没有误报/否定的风险?的主要内容,如果未能解决你的问题,请参考以下文章

如何优雅地处理用户的误操作引起的多次请求

如何使用 spark 过滤 Hive 中的记录

634. yes 和 no

如何将QT标准对话框中按钮的“Yes/No转换成中文的“是/否”?

如何让newtonsoft将yes和no反序列化为布尔值

如何优雅地使用 rm 防止误删除?