I test these codes below:
BOOL b1 = YES;
BOOL b2 = NO;
BOOL b3 = !b1;
NSNumber *num1 = @(b1);
NSNumber *num2 = @(b2);
NSNumber *num3 = @(b3);
NSNumber *num4 = @(!b1);
the objCType([num1 objCType]) type of num1, num2, num3 is "c", but the objcType of num4 is "i". Why I reverse the bool and the NSNumber's objcType is changed?
===========================
My problem is that, my origin code likes like this:
BOOL *m_bFirstEvent;
[pDict setValue:**@[[NSNumber numberWithBool:!m_bFristEvent]]** forKey:@"params"];
NSData *pPostData = [NSJSONSerialization dataWithJSONObject:pDict options:0 error:&pError];
the json string is
{"method":"getEvent", "id":7, "params":[false]}
after I use XCode's refactor->"convert to modern Objective-c syntax", the code changes to:
BOOL *m_bFirstEvent;
[pDict setValue:**@[@(!m_bFristEvent)]** forKey:@"params"];
NSData *pPostData = [NSJSONSerialization dataWithJSONObject:pDict options:0 error:&pError];
the json string is
{"method":"getEvent", "id":7, "params":[0]}
How can I avoid this NSNumber Literals mistake and safely use XCode's refactor->"convert to modern Objective-c syntax" for NSNumber Literals?
Most of the time, people don't care whether an NSNumber contains a BOOL value, or an integer with a value of 0 or 1. When you create JSON (and possibly when you process JSON), you care.
Only [NSNumber numberWithBool:xxx] or [[NSNumber alloc] initWithBool:xxx] creates an NSNumber that will be converted to true or false (and not 1 or 0) in JSON. The same if you use @YES, @NO, or @(xxx) where xxx has type BOOL, because all these eventually call initWithBool. So in your case, unfortunately Apple's conversion tool did the wrong thing.
There are actually only two NSNumber objects containing booleans ever in existence (obviously one for @YES and one for @NO). So if you process JSON, you can check for example
if (jsonResult == @YES)
NSLog (@"json data contained the value 'true'");
else if (jsonResult == @NO)
NSLog (@"json data contained the value 'false'");
else if ([jsonResult isKindOfClass:[NSNumber class]])
NSLog (@"json data contained some kind of number");
and this will distinguish between true and false, and 0, 1 or other values. Yes, the comparison with == is done on purpose and correct.
@ ((BOOL) xxx)
will create an NSNumber with a bool value. For example
@ ((BOOL) ! myBoolValue)
@ ((BOOL) (x >= 0 && x <= 100)
and so on. It seems that sometimes BOOL is signed char, and sometimes it is bool. That makes a difference if you write
@ ((BOOL) 256) // May be @YES or @NO, depending on target
@ ((BOOL) 0.3) // May be @YES or @NO, depending on target
Likewise, casting to bool instead of BOOL may or may not create a numberWithBool. Both
@ ((BOOL) (bool) 256)
@ ((BOOL) (bool) 0.3)
will produce the value @YES, because casting to bool produces 1 if the value was non-zero and 0 if it was zero; this can also be used with C pointers or object pointers.