3

Ok, so I have an NSDictionary that holds a boolean value. It's loaded from the server and parsed by the framework, and for some reason it ends up being stored as an NSCFBoolean in the dictionary (don't ask, all I know is that the -class method returns __NSCFBoolean).

Since NSCFBoolean is a framework-private class that I cannot use directly, I make a reference to it:

id myBool = myDict[@"my_bool"];

Now comes the cool part: evaluating it. I used a breakpoint and the "po" command. These are the results:

> po myBool
0

> po [myBool class]
__NSCFBoolean

> po [myBool boolValue]
<nil>

What the..?

> po myBool == true
false

> po myBool == false
<nil>

brain melts

How is it possible that == true returns false and == false returns nil?

I have a number of years of experience in programming in Objective-C but I have never seen this weird behaviour before! I've read several articles about the differences between the different boolean types and their behaviours and quirks (This article at NSHipster is quite interesting) but I've read nothing that would explain this behaviour.

Mark
  • 1,258
  • 13
  • 25
  • 2
    Most of the confusion is caused by the fact that the compiler treats `myBool` as `id` (void pointer) although `[myBool class]` prints `__NSCFBoolean`. For example this explains `[myBool boolValue]` == `nil` because `id` has no method `boolValue`. – vadian Nov 23 '18 at 11:20
  • 2
    And `> p [myBool boolValue]` returns what? Be careful with `po`, since it's object, if it' 0, often it prints nil instead of false or 0 as you expect, use `p` when it's the case for check. – Larme Nov 23 '18 at 13:49
  • `__NSCFBoolean` is returned from `@NO`, `@YES`, `[NSNumber numberWithBool:NO]` and `[NSNumber numberWithBool:YES]`. – Willeke Nov 24 '18 at 01:42
  • @Vadian [id](https://developer.apple.com/documentation/objectivec/id) is not the same as void pointer, see [What is the meaning of id?](https://stackoverflow.com/questions/7987060/what-is-the-meaning-of-id). `[myBool boolValue]` will send selector `boolValue` to `myBool`, how `myBool` is declared doesn't matter. The superclass of `__NSCFBoolean` is `NSNumber` and `[myBool boolValue]` == `nil` because `[myBool boolValue]` returns `NO` which `po` (print object) will print as ``. – Willeke Nov 24 '18 at 02:00

0 Answers0