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?