matm
matm

Reputation: 7079

How to properly use Foundation's NSString with CoreFoundation functions?

I'd like to simplify some of my keychain services code and use CFDictionarySetValue with Foundation's NSString.

Declaration of CFDictionarySetValue goes like that:

void CFDictionarySetValue(CFMutableDictionaryRef theDict, const void *key, const void *value)

so what happens when I pass e.g. @"This is a NSString" for value parameter? In my case compiler does not report a warning nor static analysis catches anything. In runtime, there's no crash, so does it mean that runtime takes care of everything, or I should pass [@"something" cStringUsingEncoding:NSUTF8StringEncoding] and cast it to const void*?

My findings show that:

NSLog(@"%s", CFDictionaryGetValue(query, kKeyForCStringInUTF8));
NSLog(@"%@", CFDictionaryGetValue(query, kKeyForNSString));

both give the same output! It's confusing...

What is a general rule with exchanging objects between CF and Foundation? Is there a generally accepted code style, a good practice?

Upvotes: 3

Views: 426

Answers (2)

Justin
Justin

Reputation: 2142

I am not sure what exactly you are asking, so I am going to expand Georg's answer. I am assuming that you need CFMutableDictionaryRef, but that you can still use MSMutableDictionary. If this is not the answer to your question, please let me know.

If I were you, I would simply use NSMutableDictionary instead, so you can simply use [yourDictionary setValue:yourString forKey:@"yourKey"];. That gets rid of one parameter, if nothing else. If you need the CFMutableDictionaryRef, just use this code:

CFMutableDictionaryRef cfDictionary = (CFMutableDictionaryRef) yourDictionary;

So then, to set and get the value, you could just do this:

// Make the objects somewhere
NSString *yourString = @"something";
NSMutableDictionary *yourDictionary = [[NSMutableDictionary alloc] init];

// now set the value...
[dictionary setObject:yourString forKey:@"Anything at all"];

// and to get the value...
NSString *value = [yourDictionary valueForKey:@"Anything at all"];

// now you can show it
NSLog(@"%@", value);

Upvotes: 1

Georg Fritzsche
Georg Fritzsche

Reputation: 98984

NSString and other types are toll-free bridged to their CoreFoundation counterparts.
See Core Foundation Design Concepts - Toll-Free Bridged Types:

There are a number of data types in the Core Foundation framework and the Foundation framework that can be used interchangeably. This means that you can use the same data structure as the argument to a Core Foundation function call or as the receiver of an Objective-C message invocation.

Upvotes: 2

Related Questions