2012-02-18 22 views
5

estoy ahorrando una gran variedad de objetos personalizados a un archivo de lista de plist de este modo:Cómo utilizar arrayWithContentsOfFile al cargar el archivo escrito con éxito con WriteToFile en ObjectiveC/XCode

+(void) arrayToPlist: (NSArray*) plant_types{ 
    NSMutableArray* dictionary_array = [NSMutableArray arrayWithCapacity: plant_types.count]; 

    for(int i = 0; i<plant_types.count; i++){ 
     PlantType* pt = [plant_types objectAtIndex: i]; 
     [dictionary_array addObject: [pt toDict]]; 
    } 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSLog(@"Writing plist to: %@", filePath); 

    [dictionary_array writeToFile: filePath atomically: YES]; 
} 

que crea un archivo que se parece a:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
<plist version="1.0"> 
<array> 
    <dict> 
     <key>name</key> 
     <string>Autumn Olive</string> 
     <key>radius</key> 
     <real>10</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Dwarf Cherry</string> 
     <key>radius</key> 
     <real>5</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Bamboo</string> 
     <key>radius</key> 
     <real>2</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Pomegranate</string> 
     <key>radius</key> 
     <real>6</real> 
    </dict> 
    <dict> 
     <key>name</key> 
     <string>Lupin</string> 
     <key>radius</key> 
     <real>0.60000002384185791</real> 
    </dict> 
</array> 
</plist> 

Y si las carga de esta manera:

+(NSMutableArray*) arrayFromPlist{ 
    NSLog(@"Loading array of plant types from plist."); 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 

    if([fileManager fileExistsAtPath:filePath]){ 
     NSLog(@"Plist file exists at expected location."); 
     NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath]; 
     NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count); 
     NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count]; 
     for(int i = 0; i< plant_dicts.count; i++){ 
      NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 
      [plant_types addObject: [PlantType fromDict: dict]]; 
     } 
     return plant_types; 
    } 
    NSLog(@"Plant Type plist file not found."); 
    return NULL; 
} 

Nothings estrellarse, pero cada vez que devuelva un NSMutableArray de tamaño cero (y esa declaración de registro confirma que plant_dicts es de tamaño cero).

¿Qué estoy haciendo mal? Todos los problemas similares que estoy viendo con arrayWithContentsOfFile: son personas que crean el plist a mano o con un editor ... Creo que hacerlo desde el código en sí no tendría estos problemas ...

Editar: I He confirmado que ya no obtengo un resultado de tamaño cero (lo cual es extraño, no ha habido cambios de código en esa sección desde la publicación original). Sin embargo, todavía no estoy cargando las cosas correctamente. Aquí están mis métodos fromDict y toDict.

El problema es que la cadena "forma" no parece cargarse correctamente. Al menos, cuando pregunto si shape == @ "Circle" entiendo que no, incluso si claramente lo hace en la declaración de NSLog. Estoy haciendo una comparación idéntica en otro lugar del código (cuando verifico cómo renderizar el objeto) y funciona bien allí (así que supongo que no hay algunos == vs .equals raros como los que hay en Java).

Edición doble: Espera, no hay [forma isEqualToString: @ "Círculo"] .... por qué no tuve que usarlo antes me confunde, pero agregarlo aquí ayuda.

+0

Sí, con cuerdas que quiere hacer isEqualToString, por la misma razón que en Java. == solo verifica que el puntero sea el mismo, no el contenido de la cadena. Eso == estaba trabajando en su código de procesamiento porque el compilador sabe que puede usar el mismo puntero para dos instancias de la misma cadena. Pero si una de esas cadenas sale de un plist, será un puntero diferente. – davehayden

Respuesta

4

Con su plist, este código de retorno un resultado correcto

+(NSMutableArray*) arrayFromPlist{ 
    NSLog(@"Loading array of plant types from plist."); 

    NSString *rootPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString* filePath = [rootPath stringByAppendingPathComponent:@"PlantTypes.plist"]; 
    NSFileManager* fileManager = [NSFileManager defaultManager]; 

    if([fileManager fileExistsAtPath:filePath]){ 
     NSLog(@"Plist file exists at expected location."); 
     NSMutableArray* plant_dicts = [NSMutableArray arrayWithContentsOfFile:filePath]; 
     NSLog(@"Loaded array with contents of file, got %d plant types.", plant_dicts.count); 
     NSMutableArray* plant_types = [NSMutableArray arrayWithCapacity: plant_dicts.count]; 
     for(int i = 0; i< plant_dicts.count; i++){ 
      NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 
      [plant_types addObject: dict]; 
     } 
     return plant_types; 
    } 
    NSLog(@"Plant Type plist file not found."); 
    return NULL; 
} 

resultado

2012-02-22 16:24:43.697 Test[5574:10103] Loading array of plant types from plist. 
2012-02-22 16:24:43.698 Test[5574:10103] Plist file exists at expected location. 
2012-02-22 16:24:43.699 Test[5574:10103] Loaded array with contents of file, got 5 plant types. 
2012-02-22 16:24:43.700 Test[5574:10103](
     { 
     name = "Autumn Olive"; 
     radius = 10; 
    }, 
     { 
     name = "Dwarf Cherry"; 
     radius = 5; 
    }, 
     { 
     name = Bamboo; 
     radius = 2; 
    }, 
     { 
     name = Pomegranate; 
     radius = 6; 
    }, 
     { 
     name = Lupin; 
     radius = "0.6000000238418579"; 
    } 
) 

Creo que el problema viene de su aplicación PlantType. Se puede publicar su código (toDict y métodos fromDict)

0

Esta línea:

NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 

no devuelve un diccionario mutable, sino una inmutable.

Si usted quiere que sea mutable, que debe hacer algo en este sentido:

MutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary: [plant_dicts objectAtIndex: i]]; 
Cuestiones relacionadas