Verhindern des kontinuierlichen autosaveInPlace mit fortlaufender Aktualisierungswertbindung

  • Die Wertbindungsoption wird fortlaufend aktualisiert und löst autosaveInPlace-Versuche (für jedes von Ihnen eingegebene Zeichen) aus.

    Hallo an alle, dies ist meine erste Frage hier!

    Ich hoffe, ich werde es richtig fragen…:)

    Ich versuche, Lions automatischen Speicherungsmechanismus zu meinem Kerndatendokument hinzuzufügen -basierte Anwendung. In meiner NSPersistentDocument-Unterklasse überschreibe ich die Methode ing the +(BOOL)autosaveInPlac e , die YES zurückgibt, und alle Funktionen funktionieren ordnungsgemäß (Speichern, neue Menüs, Versionsbrowser usw.). .

    Mein Problem ist, dass das automatisch gespeicherte System bei jedem Eingabe von Textfeldern, die mit der fortlaufenden Aktualisierungswertoption an mein Modell gebunden sind, bei jedem einzelnen Tastendruck einen Speichervorgang auslöst! Der sich drehende Strandball erscheint nicht (vielleicht, weil meine Dokumente ziemlich klein sind), aber das Tippen ist wirklich sehr langsam.

    AutosaveInPlace wird für jeden aufgerufen Drücken Sie die Taste und anschließend die Methoden saveToURL… und writeToURL… .

    Ich habe fast nichts zu diesem Thema im Netz gefunden und noch weniger in der offiziellen Dokumentation von Apple.

    In dem WWDC '11-Video "Autosave" und "Versionen" enthält der Ingenieur ein unvollständiges Beispiel für das Abbrechen eines automatischen Speichers beim [self autosavingIsImplicitlyCancellable] gibt YES zurück, aber in meinem Fall gibt diese Methode immer NO zurück. Dies muss das erwartete Verhalten sein: Der Wert muss fortlaufend aktualisiert werden, und da die Datei auf der Festplatte zu jeder Zeit mit den Inhalten übereinstimmt, die der Benutzer auf dem Bildschirm sieht, darf diese Sicherung nicht abgebrochen werden.

    Ich habe im Netz ein nützlicheres Beispiel dafür gefunden, wie verhindert werden kann, dass die Sicherung an erster Stelle initiiert wird (Überschreiben der save… -Methode anstelle der write… one).

      - (void) saveToURL: (NSURL *) URL 
     ofType: (NSString *) typeName 
     forSaveOperation: (NSSaveOperationType) saveOperation 
     completionHandler: (void (^) (NSErr.)oder * errorOrNil)) completionHandler {
     if (saveOperation == NSAutosaveInPlaceOperation) {
     if ([self isWritingInMyTextField]) {
     completionHandler ([NSError errorWithDomain: NSCocoaErrorDomain 
     Code:). nil]); 
     return; 
    } 
    } 
     [super saveToURL: URL desTyps: typeName forSaveOperation: saveOperation completionHandler: completionHandler]; 
    } 
      

    Das funktioniert. Im Falle eines automatischen Speichers, wenn mein Textfeld den Fokus hat, gebe ich den dokumentierten stillen Kakaofehler an den Beendigungs-Handler weiter und das Speichern tritt nicht auf, die Benutzeroberfläche reagiert wie zuvor. Das ursprüngliche Poster behauptet, dass das automatische Speichern auf diese Weise tatsächlich verzögert wird, bis die aktuelle Aktivität endet, aber ich bin mir nicht sicher.

    Mein Problem ist, dass ich das nicht will Ich muss jedes einzelne Textfeld für die Start- / End-Bearbeitung beobachten und manuell ein automatisches Speichern auslösen, da ich das System daran hindere, dies zu tun, während ich in Textfelder schreibe. Das System sollte nur verstehen, dass es nicht sinnvoll ist, eine Speicherung auf Tastendruckbasis auszulösen.

    Im WWDC '11-Video weist der Ingenieur auf eine Möglichkeit hin, die Benutzeraktivität zu überprüfen durch NSRunLoop und Ereignisse, aber es liegt weit außerhalb meines Verständnisses. Ich habe in der Dokumentation nach NSRunLoop , NSEvent gesucht, aber ich kann nicht herausfinden, wie man die Informationen erhält, dass der Benutzer aktiv etwas schreibt!

    Wenn mir jemand zu diesem Thema in die richtige Richtung weisen könnte, wäre ich dankbar.

    Es wäre besser, wenn jemand die empfohlene Vorgehensweise für den Umgang mit Informationen kennt zu diesem Problem!

    Als letzte Überlegung kann ich in der Dokumentation für NSPersistentDocument lesen, dass «NSPersistentDocument die asynchrone Sicherungs-API von NSDocument nicht unterstützt, da diese API Zugriff erfordert

    25 November 2011
    wdypHam Sam
2 answers
  • Hier ist meine funktionierende Antwort.

    +(BOOL)autosavesInPlace { return YES; } -(BOOL)isUserTyping { NSUInteger eventType = [[NSApp currentEvent] type]; return (eventType == NSKeyDown || eventType == NSKeyUp || eventType == NSFlagsChanged); } -(void)saveToURL:(NSURL *)url ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation completionHandler:(void (^)(NSError *errorOrNil))completionHandler { if (saveOperation == NSAutosaveInPlaceOperation) { if ([self isUserTyping]) { completionHandler([NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]); return; } } [super saveToURL:url ofType:typeName forSaveOperation:saveOperation completionHandler:completionHandler]; }

    Ich weiß nicht, ob my isUserTyping ist die beste Methode, dies zu tun. Die Verwendung der Laufschleife zur Überprüfung der Benutzeraktivität durch den WWDC ’11-Techniker bleibt mir ein Rätsel!

    25 November 2011
    wdypHam Sam
  • Ich glaube, Sie müssen die -scheduleAutosaving -Methode von NSDocument überschreiben und verhindern, dass bei aktivem Textfeld etwas ausgeführt wird.

    Die Dokumente für diesen Methodenzustand:

    Die Standardimplementierung dieser Methode prüft, ob das automatische Speichern aktiviert ist und ob und wenn [self hasUnautosavedChanges ] gibt JA zurück, plant ein NSTimer für den Aufruf von autosaveDocumentWithDelegate: didAutosaveSelector: contextInfo: in der Zukunft.

    Sie können diese Methode überschreiben, um zu steuern, wann das automatische Speichern regelmäßig abläuft.

    - (void)scheduleAutosaving { if([self checkIfOneOfYourTextFieldsIsActive]) return; //no text field is active, so just use the default behaviour [super scheduleAutosaving]; }

    Beachten Sie, dass ich nicht sicher bin, ob dies der Fall ist Arbeit, weil die Dokumente besagen, dass ein Timer für das automatische Speichern geplant ist, und ich weiß nicht, ob es möglich ist, diesen Timer in den Griff zu bekommen, damit Sie ihn aus dem Zeitplan entfernen können.

    22 November 2011
    Rob Keniger