Ich habe eine NSDocument-basierte Anwendung, die FileWrappers verwendet, um ihre Daten zu speichern und zu laden. Das Dokument kann alle möglichen Ressourcen haben, daher möchte ich nicht alles in den Speicher laden. Möglicherweise mache ich etwas grundlegend falsch, aber sobald ich eine (innere) Datei ändere und dann speichere, kann ich keine Datei lesen, die nicht in den Speicher geladen wurde.
Ich habe den relevanten Code in ein separates Projekt aufgeteilt, um dieses Verhalten zu reproduzieren, und ich erhalte die gleichen Ergebnisse. Der grundlegende Ablauf ist wie folgt:
- Ich lade ein vorhandenes Dokument von der Festplatte. Der Haupt-FileWrapper ist ein Verzeichnis-FileWrapper (den ich main nennen werde), der zwei andere FileWrappers ( sub1 und sub2) enthält. Die beiden inneren FileWrapper sind zu diesem Zeitpunkt nicht geladen.
- Wenn der Benutzer sub1 bearbeiten möchte, wird es von der Festplatte geladen.
- Der Benutzer speichert das Dokument
-
Wenn der Benutzer die andere Datei bearbeiten möchte (sub2), kann sie nicht geladen werden. Der Fehler, der erscheint:
-[NSFileWrapper regularFileContents] hat versucht, die Datei-Inhalte des FileWrappers träge zu lesen, aber ein Fehler ist aufgetreten: Die Datei konnte nicht geöffnet werden, weil sie nicht existiert.
Hier ist der relevante Code in meinem Projekt:
Dieser Code könnte einfacher in diesem Gist zu lesen sein: https://gist.github.com/bob-codingdutchmen/6869871
#define FileName01 @"testfile1.txt"
#define FileName02 @"testfile2.txt"
/**
* Nur aufgerufen bei der Initialisierung eines NEUEN Dokuments
*/
-(id)initWithType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
self = [self init];
if (self) {
self.myWrapper = [[NSFileWrapper alloc] initDirectoryWithFileWrappers:nil];
NSLog(@"Initialisiere neues Dokument...");
NSString *testString1 = @"Lorem Ipsum erste Unterdatei";
NSString *testString2 = @"Dies ist die zweite Unterdatei mit völlig unabhängigen Inhalten";
NSFileWrapper *w1 = [[NSFileWrapper alloc] initRegularFileWithContents:[testString1 dataUsingEncoding:NSUTF8StringEncoding]];
NSFileWrapper *w2 = [[NSFileWrapper alloc] initRegularFileWithContents:[testString2 dataUsingEncoding:NSUTF8StringEncoding]];
w1.preferredFilename = FileName01;
w2.preferredFilename = FileName02;
[self.myWrapper addFileWrapper:w1];
[self.myWrapper addFileWrapper:w2];
}
return self;
}
-(NSFileWrapper *)fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
// Dies würde normalerweise hier nicht passieren, aber es veranschaulicht
// wie die Inhalte der ersten Datei ersetzt würden
NSFileWrapper *w1 = [self.myWrapper.fileWrappers objectForKey:FileName01];
[self.myWrapper removeFileWrapper:w1];
NSFileWrapper *new1 = [[NSFileWrapper alloc] initRegularFileWithContents:[@"Neue Datei Inhalte" dataUsingEncoding:NSUTF8StringEncoding]];
new1.preferredFilename = FileName01;
[self.myWrapper addFileWrapper:new1];
return self.myWrapper;
}
-(BOOL)readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
self.myWrapper = fileWrapper;
return YES;
}
- (IBAction)button1Pressed:(id)sender {
// Aus Datei1 lesen und Ergebnis in Feld1 anzeigen
NSFileWrapper *w1 = [[self.myWrapper fileWrappers] objectForKey:FileName01];
NSString *string1 = [[NSString alloc] initWithData:w1.regularFileContents encoding:NSUTF8StringEncoding];
[self.field1 setStringValue:string1];
}
- (IBAction)button2Pressed:(id)sender {
// Aus Datei2 lesen und Ergebnis in Feld2 anzeigen
NSFileWrapper *w2 = [[self.myWrapper fileWrappers] objectForKey:FileName02];
NSString *string2 = [[NSString alloc] initWithData:w2.regularFileContents encoding:NSUTF8StringEncoding];
[self.field2 setStringValue:string2];
}
Die unteren beiden Methoden dienen nur zur Aktualisierung der Benutzeroberfläche, damit ich sehen kann, was passiert.
-
Um den Inhalt einer Datei zu ändern, entferne ich den vorhandenen FileWrapper und füge einen neuen hinzu. Dies ist die einzige Methode, die ich gefunden habe, um den Inhalt einer Datei zu ändern, und die Art und Weise, wie ich es in anderen SO-Antworten gesehen habe.
-
Wenn ein Dokument von der Festplatte geladen wird, halte ich den FileWrapper bereit, um ihn nutzen zu können (im obigen Code myWrapper genannt)
Laut den Apple-Dokumenten unterstützt NSFileWrapper das träge Laden und inkrementelle Speichern, daher gehe ich davon aus, dass mein Code einen grundlegenden Fehler hat, den ich nicht erkennen kann.