What is an NSCFDictionary?

14,247

Solution 1

NSDictionary and the other collection classes are actually class clusters: several concrete subclasses classes masquerading under the interface of a single class: they all provide the same functionality (because they are subclasses of the same class — in NSDictionary's case, this involves the three "primitive methods" -count, -objectForKey:, and -keyEnumerator), but have different internal workings to be efficient in different situations, based on how they're created and what type of data they may be storing.

NSCFDictionary is simply a concrete subclass of NSDictionary. That is, your NSDictionaries may actually be NSCFDictionary instances, but you should treat them as instances of NSDictionary, because that will provide you with the required dictionary-storage functionality.

NSDictionary *value = [dict objectForKey:key];

Now, another reason your code doesn't work: NSURLProtectionSpace is a class, so you should use it as a pointer, like this:

for (NSURLProtectionSpace *key ...

Solution 2

NSCFDictionary is the private subclass of NSDictionary that implements the actual functionality. It's just an NSDictionary. Just about any NSDictionary you use will be an NSCFDictionary under the hood. It doesn't matter to you code. You can type the variable as NSDictionary and use it accordingly.

Share:
14,247
JPC
Author by

JPC

Updated on June 26, 2022

Comments

  • JPC
    JPC almost 2 years

    I'm getting an NSCFDictionary returned to me and I can't figure out how to use it. I know it's of type NSCFDictionary because I printed the class and it came out as __NCSFDictionary. I can't figure out how to do anything with it.

    I'm just trying to hold onto it for now but can't even get that to work:

      NSDictionary *dict = [[NSURLCredentialStorage sharedCredentialStorage] allCredentials];
      for(NSURLProtectionSpace key in [dict keyEnumerator])
      {
             NSCFDictionary *value = [dict objectForKey:key];
      }
    

    The class reference for allCredentials says its supposed to return a dictionary whose values are also dictionaries. My assignment statement isn't working though. Do I need a cast of some kind?

  • JPC
    JPC over 12 years
    hmm then how come this doesn't work...NSDictionary *value = [dict objectForKey:key];
  • JPC
    JPC over 12 years
    I tried just using NSDictionary but it wouldn't compile. Maybe it's an Xcode issue
  • Nico
    Nico over 12 years
    @JPC: Assuming dict holds a pointer to an object that responds to objectForKey:, such as another instance of NSDictionary (or of any subclass thereof), that works just fine.
  • Nico
    Nico over 12 years
    @JPC: One important distinction that bears on this problem is that the type of object you get returned to you at run time (in this case, NSCFDictionary instead of NSDictionary directly) will not cause a problem at compilation time. Compilation happens before execution; if the compiler shows you an error while building the program, nothing that would happen if you could run it is relevant.
  • Magic Bullet Dave
    Magic Bullet Dave over 11 years
    I have a similar issue, where I want to check if the class of the object is a certain type (NSString, NSNumber, NSData, NSDictionary or NSArray). The class of the object returns NSCFString, NSCFDictionary, etc. which means my check fails. Is there a way around this?
  • csiu
    csiu over 11 years
    @MagicBulletDave Use isKindOfClass: for this: stackoverflow.com/a/6840896/23649 (while, e.g., an NSString object may at runtime be something like NSCFString, it will always be a subclass of NSString itself).
  • uchuugaka
    uchuugaka almost 10 years
    Actually the part missing here is that NSDictionary is toll-free bridged to CFDictionary and both will in most cases actually create an instance of NSCFDictionary.