Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare @NO and @YES with elegance and without risk of false positives/negatives?

I want to use bool literals like

if (condition == @NO) {

}
else if (condition == @YES) {

{

When I try this, XCode wants me to use NSNumber methods to compare, like isEqualTo. Is there a simpler way to do this (without isEqualTo)? If I can't, should I use isEqualTo, isEqualToValue, or isEqualToNumber?

like image 899
zakdances Avatar asked Mar 25 '13 03:03

zakdances


3 Answers

What is condition? Is it a BOOL or an NSNumber?


If condition is a BOOL, then you don't want to use @NO or @YES at all. You want to say

if (condition) // test if condition is true

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

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

Note that you should never say

if (condition == YES)

because BOOL isn't actually restricted to 0 and 1 as values, it can hold anything in char, so if condition accidentally holds, say, 3, then if (condition) and if (condition == YES) would behave differently.


If condition is an NSNumber, then you still don't want to use @NO and @YES. You just want to convert it to a BOOL using -boolValue, as in

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

The basic takeaway here is, don't use @NO and @YES literals for comparisons. It's pointless, and inelegant, since all you'd be able to do with them is convert them back into BOOLs.

like image 98
Lily Ballard Avatar answered Nov 04 '22 02:11

Lily Ballard


Assuming the data type of condition is BOOL, then you want:

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

If condition is an NSNumber then use:

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

If condition is based on some arbitrary numbers then treat 0 as NO and treat non-zero as YES.

Again, if condition is an NSNumber then do:

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

Update: Based on the following comment from the OP:

Condition is a bool, like if (myView.frame.size.height == 30)

This implies that the actual question wanted to do checks something like:

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

This is very unusual. The proper thing to do is:

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

There is no need to worry about false positives or negatives. The condition is either true or it isn't. There is no 3rd possibility. If the condition gives the wrong result then the solution is to fix the condition.

like image 5
rmaddy Avatar answered Nov 04 '22 04:11

rmaddy


You can save @NO in a dictionary because @NO is an object. You cannot save NO in a dictionary. So use @NO.boolValue when needed. For example:

NSDictionary *userSetting = (NSDictionary *)[[NSUserDefaults standardUserDefaults] objectForKey:@"user"];
//Suppose you have done: userSetting[@"canWriteCode"] = @YES;
if ([userSetting[@"canWriteCode"] boolValue])
    [self helloProgrammer];
like image 2
jack Avatar answered Nov 04 '22 02:11

jack