Pregunta

Estoy escribiendo un juego usando cocos2d-iPhone y nuestros estadios se definen en los archivos plist. Sin embargo, los archivos están creciendo grande - por lo que he desarrollado un editor que añade un poco de estructura al proceso y se rompe la mayoría de la plist hacia abajo en campos fijos. Sin embargo, algunos elementos todavía requieren funcionalidad de tipo editor de plist, por lo que han implementado un NSOutlineView en los paneles que muestran otros parámetros ''. Estoy tratando de duplicar la funcionalidad de XCode de 'propiedad editor de listas'.

He implementado el sistema siguiente; http://www.stupendous.net/archives/2009/01/ 11 / nsoutlineview-ejemplo /

Esto es muy parecido a lo que necesito, pero hay un problema que he pasado la mayor parte de hoy intentando resolver. Los valores para la columna de clave corresponden al revés 'del elemento seleccionado al encontrar el diccionario de los padres y el uso;

return [[parentObject allKeysForObject:item] objectAtIndex:0];

Sin embargo, cuando hay múltiples elementos con el mismo valor dentro de un diccionario dado en el árbol, esta declaración siempre devuelve el primer elemento que tiene ese valor (que aparece al comparar las cadenas utilizando isEqualToString: o valores hash). Esto conduce a la columna que muestra clave 'elemento1, elemento1, elemento1' en lugar de elemento1, elemento2, elemento3 (donde los artículos 1-3 todos tienen valor ''). Yo probé siguiente;

-(NSString*)keyFromDictionary:(NSDictionary*)dict forItem:(id)item
{
for( uint i = 0; i < [[dict allKeys] count]; i++ ) {
    id object = [dict objectForKey:[[dict allKeys] objectAtIndex:i]];

    if ( &object == &item ) {
        return [[dict allKeys] objectAtIndex:i];
    }
}   

return nil;
}

Pero esto siempre devuelve nil . Tenía la esperanza de que alguien con un poco más de experiencia con NSOutlineView podría ser capaz de proporcionar una mejor solución. Si bien este problema sólo aparece una vez en el ejemplo relacionado, he tenido que usar esto varias veces al borrar los artículos en los diccionarios, por ejemplo. Cualquier ayuda sería muy apreciada.

¿Fue útil?

Solución

return [[parentObject allKeysForObject:item] objectAtIndex:0];

Sin embargo, cuando hay múltiples elementos con el mismo valor dentro de un diccionario dado en el árbol, esta declaración siempre devuelve el primer elemento que tiene ese valor ...

Bueno, sí. Eso es lo que dijo que hiciera: “Tráeme todas las claves para este valor; conseguirme el primer elemento de la matriz; devolver ese”.

... esta declaración siempre devuelve el primer elemento que tiene ese valor (que aparece al comparar las cadenas utilizando isEqualToString: o valores hash).

No es que la declaración de que lo está haciendo; es la forma en diccionarios de trabajo: Cada tecla sólo puede encontrarse en el diccionario una vez y sólo puede tener exactamente un objeto como su valor, y esto se aplica utilizando el hash de la clave y enviando las teclas isEqual: mensajes (no el isEqualToString:- NSString específica llaves no están obligados a ser cadenas *).

Los valores, por el contrario, no son uniquified. Cualquier número de teclas puede tener el mismo valor. Es por eso que al pasar de los valores de las teclas, y especialmente a a clave es tan problemático.

* No está en NSDictionary, de todos modos. Cuando intenta generar la salida plist, será vomitar si el diccionario contiene ninguna clave que no son cadenas.

Me trató próxima;

-(NSString*)keyFromDictionary:(NSDictionary*)dict forItem:(id)item
{
    for( uint i = 0; i < [[dict allKeys] count]; i++ ) {
        id object = [dict objectForKey:[[dict allKeys] objectAtIndex:i]];

        if ( &object == &item ) {
            return [[dict allKeys] objectAtIndex:i];
        }
    }   

    return nil;
}

Pero esto siempre devuelve nil.

Ese es el menor de los problemas de ese código.

En primer lugar, cuando se repite en una NSArray, por lo general, no debe utilizar índices menos que sea absolutamente necesario. Es mucho más limpio para usar enumeración rápida .

En segundo lugar, cuando haces índices necesidad en un NSArray, el tipo correcto es NSUInteger. No mezclar y combinar tipos cuando se puede evitar.

En tercer lugar, no sé lo que quería decir que ver con el operador de dirección, pero lo que realmente hizo fue tomar la dirección de esas dos variables. Por lo tanto, usted comparó si la object variable local es la misma variable como la variable argumento item. Ya que no son la misma variable, que siempre devuelve prueba falsa, que es por eso que nunca devuelven un objeto, el único otro punto de salida vuelve nil, y eso es lo que siempre sucede.

El problema con este código y la anterior de una sola línea es que usted está tratando de pasar de un valor a una sola tecla, lo que es contrario a la forma de trabajo diccionarios: Sólo las teclas son únicos; cualquier número de teclas puede tener el mismo valor.

Se necesita usar algo más que los artículos. Utilizando las teclas como los artículos sería una forma; hacer una modelo de objetos para representar cada fila sería otro.

Si vas a la ruta modelo de objeto, no se olvide de prevenir varias filas en el mismo diccionario virtual a partir de tener la misma clave. Un NSMutableSet además la implementación de hash y isEqual: ayudaría con eso.

Es probable que también debe realizar el mismo cambio a su manejo de matrices.

Otros consejos

Para aclarar, finalmente resuelto este problema mediante la creación de objetos proxy para cada una de las colecciones en el archivo plist (así, por cada NSMutableArray o NSMutableDictionary). Esto significaba que esencialmente Reflejé la estructura Plist y incluido referencias de nuevo a los objetos originales en cada nivel. Esto me permitió almacenar el índice de matriz para cada objeto o la clave de diccionario, por lo que cuando los elementos de ahorro de vuelta de la vista de esquema de las estructuras plist, he utilizado la 'llave' o propiedades 'índice' en el objeto proxy.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top