2012-04-11 7 views
0

Ich bin derzeit in Lesen und Schreiben in eine PLIST-Datei. Hier ist mein aktueller Stand: Ich habe eine Plist-Datei mit dem Namen "Scores.plist" erstellt und sie in meinen Resources-Ordner für mein xcode-Projekt gestellt. Innerhalb der PLIST-Datei enthält ein Wörterbuch mit dem Schlüssel "Score". Das an den Schlüssel angehängte Objekt ist eine NSNummer mit einem Platzhalterwert von 1010. Wenn ich meinen Code ausführe, bekomme ich merkwürdige Ergebnisse. Ist mein PLIST am falschen Ort? Ich höre, dass die PLIST in einigen Dokumenten-Verzeichnis, zum Lesen und Schreiben. Ich bin mir aber nicht sicher, wo genau das ist. Jede Hilfe wird geschätzt. Danke im Voraus! :)Schreiben und Lesen von einer Plist-Datei

-(void)writeToPlistHighScore:(int)scoreNumber { 
    //attempt to write to plist 
    //however both the nslog's in this first section result in "null" 
    NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 
    NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"Scores.plist"]; 

//NSString *scorePath2 = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"]; 
NSDictionary *plistDict = [[NSDictionary dictionaryWithContentsOfFile:filePath] retain]; 
NSLog(@"%@",[plistDict objectForKey:@"Score"]); 
[plistDict setObject:[NSNumber numberWithInt:scoreNumber] forKey:@"Score"]; 
[plistDict writeToFile:filePath atomically: YES]; 
NSLog(@"%@",[plistDict objectForKey:@"Score"]); 
[plistDict release]; 

//Stable code for reading out dictionary data 
//this code reads out the dummy variable in Scores.plist located in my resources folder. 
// Path to the plist (in the application bundle) 
NSString *scorePath = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"]; 
NSDictionary *plistData = [[NSDictionary dictionaryWithContentsOfFile:scorePath] retain]; 
NSString *scoreString = [NSString stringWithFormat:@"Score:%@", [plistData objectForKey:@"Score"]]; 
NSLog(@"%@",scoreString); 

//checking to see where my file is... 
//this logs a file path which I don't know means 
NSError *error; 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
NSString *documentsDirectory2 = [paths objectAtIndex:0]; 
NSString *path = [documentsDirectory2 stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.plist",@"Scores"]]; 

NSFileManager *fileManager = [NSFileManager defaultManager]; 

if (![fileManager fileExistsAtPath: path]){ 
    NSLog(@"File don't exists at path %@", path); 

    NSString *plistPathBundle = [[NSBundle mainBundle] pathForResource:@"Scores" ofType:@"plist"]; 

    [fileManager copyItemAtPath:plistPathBundle toPath: path error:&error]; 
}else{ 
    NSLog(@"File exists at path:%@", path); 
} 

}

Antwort

1

Die kurze Antwort ist, dass Sie NSDocumentDirectory statt NSLibraryDirectory verwenden möchten.

NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0]; 

Sie möchten das Dokumentendokument Ihrer Anwendung in der Sandbox speichern, nicht im Anwendungsbundle. Sie dürfen zur Laufzeit in Ihrem Anwendungspaket nichts ändern.

siehe http://developer.apple.com/library/mac/#documentation/FileManagement/Conceptual/FileSystemProgrammingGUide/FileSystemOverview/FileSystemOverview.html für eine vollständige Erklärung.

Jetzt ist der Trick, was ist, wenn Sie eine Standard-Plist-Datei laden möchten, wenn eine noch nicht gespeichert wurde? Nun, überprüfen Sie zuerst Ihr Dokumentenverzeichnis und, wenn dort keine Datei gespeichert wurde, laden Sie eine Vorlage aus Ihrem Ressourcenverzeichnis. Noch besser, wenn es eine so einfache Struktur ist, wie es scheint, erstellen Sie einfach das NSDictionary im Code und speichern Sie es dann mit writeToFile: atomically :, das im plist-Format schreiben wird.

Es gibt eine nette Erklärung der Handhabung von plist unter http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/PropertyLists/QuickStartPlist/QuickStartPlist.html#//apple_ref/doc/uid/10000048i-CH4-SW5. Es verwendet eine Mac OS X App als Beispiel, aber die Konzepte sind auf iOS übertragbar.

Übrigens, Sie machen einige unnötige Schritte mit Ihren behält und Freigaben. dictionaryWithContentsOfFile erstellt ein Objekt mit Autorelease, sodass Sie es nicht beibehalten müssen. Daher müssen Sie es nicht später freigeben. Sie können das Gleiche erreichen Sie mit in Ihrem ersten Code-Block zu tun:

NSDictionary *plistDict = [NSDictionary dictionaryWithContentsOfFile:filePath]; 
NSLog(@"%@",[plistDict objectForKey:@"Score"]); 
[plistDict setObject:[NSNumber numberWithInt:scoreNumber] forKey:@"Score"]; 
[plistDict writeToFile:filePath atomically: YES]; 
NSLog(@"%@",[plistDict objectForKey:@"Score"]); 

plistDict Autoreleased wird, wenn die aktuelle Iterierten Laufschleife. Ich erwähne das, weil Sie PlistData später in Ihrem Beispiel nicht freigeben, was ein Speicherverlust ist, wenn es später nicht veröffentlicht wird, während Sie vermeiden könnten, indem Sie plistData einfach nicht beibehalten. Eine ausführliche Erläuterung der automatisch freigegebenen Objekte finden Sie unter https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI.