2010-02-17 12 views
8

Me gustaría iterar a través de CFDictionary (CFPropertyList) y obtener todos los valores en un nivel específico.Cómo enumerar claves CFProperyList/CFDictionary

Esto sería mi diccionario/propiedad lista:


root 
    
    A 
    
    foo 
    0 
    bar 
    0 
    
    B 
    
    foo 
    10 
    bar 
    100 
    
    C 
    
    foo 
    20 
    bar 
    500 
    
    

Usando ObjC se vería algo como esto:

//dict is loaded with the dictionary below "root" 
NSDictionary *dict = [...]; 
NSEnumerator *enumerator = [dict keyEnumerator]; 
NSString *key; 
while (key = [enumerator nextObject]) 
{ 
    NSLog(key); 
}; 
 

Y sería imprimir una lista de claves a la consola como esto:

 
A 
B 
C 

¿Cómo se consigue esto cuando usando C/C++ en el nivel de CoreFoundation?

Respuesta

10

basado en el código de SeeMyFriends:

CFDictionaryRef dict = CFDictionaryCreate(...) 
size size = CFDictionaryGetCount(dict); 
CFTypeRef *keysTypeRef = (CFTypeRef *) malloc(size * sizeof(CFTypeRef)); 
CFDictionaryGetKeysAndValues(dict, (const void **) keysTypeRef, NULL); 
const void **keys = (const void **) keysTypeRef; 

Ahora puede caminar a través de los punteros en keys[]. No se olvide de free(keys) cuando haya terminado.

Recuerde que las claves del diccionario no son cadenas. Son void* (por lo que se tomaron la molestia de emitir keysTypeRef en keys). También tenga en cuenta que solo agarré las llaves aquí, pero también podría obtener valores al mismo tiempo. Vea el código SeeMyFriends para obtener un ejemplo más detallado.

+0

gracias un montón - que hizo el trabajo. – Till

+0

El método CFDictionaryGetKeysAndValues ​​toma un puntero a un puntero a una matriz de teclas. ¿Por qué, entonces, no pasa la dirección del puntero "keysTypeRef" (que sería un puntero a ese puntero)? – erikprice

+0

'CFDictionaryGetKeysAndValues' toma un puntero a una matriz de punteros (' void ** '), no un puntero a un puntero a una matriz de punteros (' void *** '). Recuerde, 'CFTypeRef' en sí mismo es un puntero. –

41

Use CFDictionaryApplyFunction para repetir en un diccionario.

static void printKeys (const void* key, const void* value, void* context) { 
    CFShow(key); 
} 
... 
CFDictionaryApplyFunction(dict, printKeys, NULL); 
+0

Muy elegante - gracias! – Till

+1

De acuerdo. Un excelente enfoque para una amplia variedad de problemas. –

4

CFCopyDescription es útil cuando se depura ...

CFCopyDescription 
Returns a textual description of a Core Foundation object. 

    CFStringRef CFCopyDescription (
     CFTypeRef cf 
    ); 
Cuestiones relacionadas