问题
I want to compare 2 BOOL values in objective-c.
I found out that (3)-(6) of the following code works.
(1)-(2) doesn't work because BOOL is just signed char
.
(3) works and is very readable but I think bool
isn't objective-c.
Using bool
in objective-c code is good?
Which is the safe and good way to compare 2 BOOL values in objective-c?
Are there other better ways to compare?
BOOL b = YES;
BOOL c = 2;
NSLog(@"(1) %d", b == c); // not work
NSLog(@"(2) %d", (BOOL)b == (BOOL)c); // not work
NSLog(@"(3) %d", (bool)b == (bool)c);
NSLog(@"(4) %d", !b == !c);
NSLog(@"(5) %d", !!b == !!c);
NSLog(@"(6) %d", (b != 0) == (c != 0));
results:
(1) 0
(2) 0
(3) 1
(4) 1
(5) 1
(6) 1
回答1:
It's perfectly valid to use bool
in Objective-C as it's part of the C99 standard (§7.16). In my opinion it's also the best way to handle safe comparisons of boolean types.
The only reason not to use bool
everywhere is that BOOL
is omnipresent in Objective-C and the frameworks.
回答2:
Comparing two boolean values should be handled with an XOR operation.
Trying to compare the two booleans directly is a misuse of the fundamentals of Boolean Algebra: http://en.wikipedia.org/wiki/Boolean_algebra_(logic)
When you are doing
BOOL a = (b == c);
then this value may return false even if both b and c are true. However the expression b && c will always return YES if both b and c are true, i.e. greater than 0, and NO otherwise.
Instead this is what you are actually trying to do:
BOOL xor = b && !c || !b && c;
BOOL equal = !xor;
equivalent with
BOOL equal = !(b && !c || !b && c);
or
BOOL equal = (b && c) || (!b && !c)
If you have to spend time making sure that your BOOL values are normalized (i.e. set to either 1 or 0) then your doing something wrong.
回答3:
apart from the other answers, I would like to note that comparing bools for equality is not a very common operation. BOOL
is not a type, it's just a macro which hides the fact that booleans are only integers. For every boolean operation, you should rather use programming structures and operators that can handle integers as booleans correctly:
e.g:
if (condition1 == NO) {}
should be if (!condition1) {}
if (condition1 == condition2) {}
can beif ((condition1 && condition2) || (!condition1 && !condition2)) {}
or betterBOOL newCondition = (condition1 && condition2) || (!condition1 && !condition2);
if (newCondition) {}
The shortest way to write a condition doesn't have to be the best way.
回答4:
Convert your number to a valid BOOL
, by answering what do you mean by "2"
in your context, is 2 = YES
Int number = 2;
BOOL c = (number == 2); //2 is YES
is > 0 = YES
Int number = 2;
BOOL c = (number > 0); //2 is YES
It depends manly on what is TRUE and what is False in your application
回答5:
From objc.h
:
typedef signed char BOOL;
....
#define YES (BOOL)1
#define NO (BOOL)0
Apparently, BOOL is signed char
, so it is true that you can assign number to variable of BOOL
type, which will mess up the comparison (since the comparison is integer comparison).
I think your (4) method using negation to convert arbitrary integral value to 0 or 1 is a good short way to safely compare the logical value of 2 BOOL.
回答6:
If you assign the integer 2 to a variable of type BOOL, your code is broken. Whatever you get after that, it's what you deserve.
Therefore, the only sensible way to compare two BOOLs a and b is
if (a == b) ...
if (a != b) ...
来源:https://stackoverflow.com/questions/11134352/in-objective-c-safe-and-good-way-to-compare-2-bool-values