2012-02-18 17 views
5

jestem oszczędność tablicę obiektów niestandardowych na liście plików plist tak:Jak korzystać arrayWithContentsOfFile załadować plik z powodzeniem napisane z WriteToFile w 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]; 
} 

który tworzy plik, który wygląda tak:

<?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> 

i załadunek do nich w ten sposób:

+(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 upaść, ale za każdym razem zwraca NSMutableArray o rozmiarze zero (i ta instrukcja rejestrowania potwierdza, że ​​plant_dicts ma rozmiar zero).

Co robię źle? Wszystkie podobne problemy, które widzę z arrayWithContentsOfFile:, to ludzie tworzący plist ręcznie lub z edytorem ... Myślę, że zrobienie tego z samego kodu nie miałoby takich problemów ...

Edytuj: I potwierdziły, że nie uzyskuję już wyniku o wielkości zerowej (co jest dziwne, nie było żadnych zmian w kodzie w tej sekcji od czasu pierwotnego wpisu). Jednak nadal nie ładuję rzeczy poprawnie. Oto moje metody odDict i ToDict.

Problem polega na tym, że ciąg "kształt" prawdopodobnie nie ładuje się prawidłowo. Przynajmniej, gdy pytam, czy kształt == @ "Kółko", widzę, że tak nie jest, nawet jeśli wyraźnie ma to miejsce w oświadczeniu NSLog. Dokonuję identycznego porównania w innym miejscu w kodzie (podczas sprawdzania, jak renderować obiekt) i działa dobrze (więc zakładam, że nie ma jakiegoś dziwnego == vs .równania jak w Javie).

Podwójna edycja: Czekaj, nie ma [shape isEqualToString: @ "Circle"] .... dlaczego nie musiałem go używać, zanim mnie pomyli, ale dodanie go tutaj pomaga.

+0

Tak, z ciągami chcesz zrobić isEqualToString, z tego samego powodu co w Javie. == sprawdza tylko, czy wskaźnik jest taki sam, a nie zawartość łańcucha. To == działało w kodzie renderowania, ponieważ kompilator wie, że może użyć tego samego wskaźnika dla dwóch wystąpień tego samego ciągu znaków. Ale jeśli jeden z tych łańcuchów wychodzi z plistu, będzie to inny wskaźnik. – davehayden

Odpowiedz

4

Dzięki swojej plist, kod ten zwraca poprawny wynik

+(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; 
} 

wynik

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"; 
    } 
) 

myślę problemem pochodzą z implementacji PlantType. Można pisać kod (metody toDict i fromDict)

0

wiersz:

NSMutableDictionary* dict = [plant_dicts objectAtIndex: i]; 

nie zwraca zmienny słownika, ale niezmienny jeden.

Jeśli ma to być zmienny, należy zrobić coś wzdłuż tych linii:

MutableDictionary* dict = [NSMutableDictionary dictionaryWithDictionary: [plant_dicts objectAtIndex: i]]; 
Powiązane problemy