Boolean as a property in Cocoa
I'm sure that this has been asked MANY times before, but it's still giving me trouble. I define my class's Boolean property like this:
@property(readwrite,assign) BOOL namesVisible;
开发者_C百科
And it doesn't give compiler errors, but it NSLogs as (null). Obviously I'm doing something wrong here, but I'm at a loss to what it is.
BOOLs are just chars, either 0 or 1. As such, you don't need to use a storage keyword in the property declaration, so it should be:
@property (readwrite) BOOL namesVisible;
Second, when logging a BOOL, use the int format string, %d, or pass in a string:
NSLog(@"My Boolean: %d, or %@", object.namesVisible, object.namesVisible ? @"Yes" : @"No");
Because you're trying to log it as an object by using %@
, and a BOOL
isn't an object, and your property's value is NO
and you're lucky.
The last part is because you're only passing a BOOL
to NSLog
, but since your format string says to expect an object pointer, it will read a pointer's worth from the argument stack. Since a pointer is bigger than a BOOL
, it's reading more than you passed it. You're lucky that it got zeroes for all four/eight bytes (your NO
was only one of them); the result is that it sent its description
message to nil
, which returned nil
for the description string, which prints as “(null)” in the output.
If you'd been unlucky and/or the property's value had been YES
, it would have read something that isn't nil
, but is nonetheless probably not a pointer to an object that exists. As such, trying to log that would cause a crash, probably of the EXC_BAD_ACCESS
variety. If you'd been unlucky and lucky at the same time, you would have printed the description of an actual object, and wondered how the hell your BOOL
looked like that.
The solution is one of two things:
NSLog(@"My Boolean property: %d", (int)[myObject myBooleanProperty]);
or:
NSLog(@"My Boolean property: %@", [myObject myBooleanProperty] ? @"YES" : @"NO");
The former casts the Boolean value to a full-size int
and prints that value as such (most probably either 0 or 1), whereas the latter will pass either @"YES"
or @"NO"
as the argument depending on the Boolean value. Since NSString literals are (NSString) objects, the %@
formatter becomes the right one.
精彩评论