简体   繁体   中英

Why does the unary bit inversion operator not invert the value of a BOOL?

I want to invert the value of a BOOL every time I detect a tap. The default value of the BOOL is NO and the first time I tap it inverts it to YES . On subsequent taps the value stays as YES .

@property(nonatomic, assign) BOOL isDayOrNight; //property in timeDayChart object.

self.timeDayChart.isDayOrNight = ~self.timeDayChart.isDayOrNight; //This is done in a VC. 

I had to change it to this:

self.timeDayChart.isDayOrNight = !self.timeDayChart.isDayOrNight;

to achieve my desired results. I would like to know why ~ did not work as expected.

BOOL is defined as a signed char in objc.h:

typedef signed char     BOOL; 

and YES and NO are defined like so:

#define YES             (BOOL)1
#define NO              (BOOL)0

So ~YES is -2, which is not the same as NO.

In (Objective-)C(++) when a Boolean value is required, such as in an if or as an operand to && , actually take an integer value and interpret 0 as false and non-zero as true. The logical, relational and equality operators all also return integers, using 0 for false and 1 for true.

Objective-C's BOOL is a synonym for signed char , which is an integer type, while NO and YES are defined as 0 and 1 respectively.

As you correctly state ~ is the bit inversion operator. If you invert any integer containing both 0's and 1's the result will also do so. Any value containing a 1 bit is treated as true, and inverting any such value other than all 1's produces a value with at least one 1 bit which is also interpreted as true.

If you start with all 0's then repeated inversion should go all 1's, all 0's, all 1's - which is true, false, true etc. (but not YES, NO, YES, etc.). So if you are starting with 0 then either you are not always using inversion or you are testing explicitly for YES rather than true.

However what you should be using, as you figured out, is ! - logical negation - which maps 0 to 1 and non-0 to 0 and so handles "true" values other than 1 correctly.

HTH

Find a book about the C language. Check what it says about the ~ operator and the ! operator. ~ inverts all bits in an integer, and BOOL is defined as an integer type. So NO = all bits zero will be changed to all bits set, which is not the same as YES, and YES = all bits zero except the last bit = 1 will be changed to all bits set except the last bit = 0.

You are better off using this idiom to toggle a BOOL value:

self.timeDayChart.isDay = self.timeDayChart.isDay ? NO : YES;

(I deliberately changed the naming of your property)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM