Wie können Sie die NSDocument-Methode -canCloseDocumentWithDelegate: shouldCloseSelector: contextInfo: in Swift implementieren?

In meiner Bewerbung einNSDocument unternehmenskritische Hardware der Unterklasse - Benutzer möchten ein Dokument nicht versehentlich schließen! Also habe ich @ implementiecanCloseDocumentWithDelegate… um ein @ anzuzeigNSAlert und vor dem Schließen fragen.

Ich versuche jetzt, dasselbe in eine in Swift geschriebene Anwendung zu implementieren.

Sobald die Antwort asynchron eingeht, wird das Ergebnis "sollte schließen" an einen Rückruf eines Delegaten übergeben und nicht einfach zurückgegeben. In der Dokumentation zu-canCloseDocumentWithDelegate:shouldCloseSelector:contextInfo:, es sagt

Die Rückrufmethode shouldCloseSelector sollte die folgende Signatur haben:

- (void)document:(NSDocument *)doc shouldClose:(BOOL)shouldClose contextInfo:(void *)contextInfo

So, da es 3 verschiedene Argumente gibt, kann ich das einfache @ nicht verwendeperformSelector:withObject: style Methoden - Sie müssen NSInvocation verwenden. Beachten Sie, dass der Delegat vom Typ @ isid und die obige Signatur erscheint in keinem formalen Protokoll - Sie können die Methode nicht einfach normal aufrufen. (Sieh dir das anmailing list post zum Beispiel, wie das gemacht werden soll)

Nun, das Problem ist, NSInvocation ist in Swift nicht erlaubt! Siehe Swift Blog "Was ist mit NSMethodSignature passiert?":

Bringing the Cocoa Frameworks zu Swift gab uns die einmalige Gelegenheit, unsere APIs aus einer neuen Perspektive zu betrachten. Wir fanden Klassen, die wir nicht für die Ziele von Swift hielten, meistens aufgrund der Priorität, die wir der Sicherheit beimessen. Beispielsweise werden einige Klassen, die sich auf den dynamischen Methodenaufruf beziehen, in Swift nicht verfügbar gemacht, nämlichNSInvocation undNSMethodSignature.

Das hört sich gut an, fällt aber runter, wenn ein einfachesNSDocument API benötigt noch NSInvocation! Die wirkliche Lösung für dieses ganze Problem wäre, dass Apple ein neues @ einführcanCloseDocument… API mit einem Block-Callback. Was ist bis dahin die beste Lösung?

Antworten auf die Frage(8)

Ihre Antwort auf die Frage