Wie in meinen Kommentaren erwähnt, bin ich unklar, warum dies sollte nicht funktionieren. Die documentation gibt nichts zu empfehlen, dies sollte nicht funktionieren, aber es gibt auch nicht explizit, dass es sollte. Meine Lektüre der Dokumentation sagt, dass es funktionieren sollte.
dies gesagt wurde, wir könnte wickeln diese in einem Verfahren, das von Objective-C, indem die Rücklauftyp Void
und unter Verwendung eines inout
Parameter für das Ergebnis aufrufbar ist:
func doSomething(value: Int) throws -> Bool {
if (value > 0) {
return true
} else if (value < 0) {
return false
} else {
throw NSError(domain: "SwiftClass", code: 0, userInfo: nil)
}
}
func doSomething(value: Int, inout result: Bool) throws {
do {
result = try doSomething(value)
} catch let error {
// If need be, assign some default value to result.
throw error
}
}
Alternativ kann, wie pro Ihren Kommentar, scheint es der Compiler glücklich sein würde, wenn wir einen Wert zurückgeführt, die zu einer Objective-C-Klasse überbrücken kann (die offenbar nicht Bool
nicht enthalten), so konnten wir sie als solche wickeln:
@objc func doSomething(value: Int) throws -> NSNumber {
do {
return try doSomething(value)
} catch let error {
throw error
}
}
Und beim Herumspielen wurde klar warum das funktioniert nur, wenn wir einen Wert zurückgeben, der einer Objective-C-Klasse zugeordnet werden kann.
Der Compiler lässt Sie keine optionale von einer mit @objc
und throws
gekennzeichneten Methode zurückgeben. Warum? Da wir auf der Swift-Seite try
Semantik verwenden, um die Methode aufzurufen, ist der Ansatz in Objective-C völlig anders. nil
wird verwendet, um einen Fehler anzuzeigen.
So versucht, eine Methode mit diese Signatur in Swift zu erstellen:
@objc func doSomething(value: Int) throws -> NSNumber?
generiert diese Warnung:
Methode Werfen kann nicht @objc markiert werden, da sie einen Wert von optionalen Typ zurückgibt 'NSNummer?'; ‚Entfällt‘ zeigt einen Fehler in Objective-C
Am Ende aber ich immer noch sehr empfehlen, dass Sie die Swift-Methode als mit der Unterschrift Rückkehr Bool
und schreiben eine Wrapper Methode Rückkehr NSNumber
so schreiben, dass Wir haben immer noch unsere Swift-Methode mit dem genauesten möglichen Typ.
Auch, wenn Sie bemerken, Bool
kann glücklich automatisch Box in NSNumber
. Meine Wrappermethode wurde als zurückkehrender Typ NSNumber
geschrieben, aber die Methode, die ich umschließe, gibt den Typ Bool
zurück, aber Swift war vollkommen glücklich, Bool
von einer Methode zurückzugeben, die NSNumber
zurückgeben soll. Das Problem ist höchstwahrscheinlich, dass Swifts Bool
standardmäßig in Objective-C BOOL
übersetzt wird, was eine Nicht-Klasse ist.
Objective-C könnte zwischen den drei möglichen Fällen nicht unterscheiden, wenn Ihr Rückgabetyp BOOL
lautet. Es hat nur zwei mögliche Rückgaben von einer BOOL
Methode: YES
oder NO
. Mit Bool
, das einem NSNumber
zugeordnet ist, kann es @YES
, @NO
und nil
zurückgeben.
Und wenn ich es bin, ist NSNumber
nicht wirklich streng genug für mich. Ich könnte dazu ermutigt werden, dafür meine eigene eingewickelte Klasse zu schreiben.
@objc class BooleanObject: NSObject, BooleanType {
let boolValue: Bool
init(_ boolValue: Bool) {
self.boolValue = boolValue
}
}
Beachten Sie, dass die BooleanType
Protokoll bedeutet, dass Swift würde immer noch vollkommen glücklich Variablen dieses Typs zu verwenden, als ob sie eine regelmäßige Bool
waren.
let b = BooleanObject(true)
if b {
// b's boolValue property is true
}
Hmm, können Sie ein 'return' nach dem' throw' im ersten Beispiel hinzufügen? Wenn in Swift eine Methode ausgelöst wird, gibt sie nichts zurück. In Objective-C führt das Festlegen des Fehlerparameters nicht dazu, dass Sie einen gültigen Wert zurückgeben. – nhgrif
Ich habe das getan (und die Frage aktualisiert, um die Änderung zu übernehmen). Kein Unterschied – Paulw11
Dieses Makro beeinflusst die Sichtbarkeit von Objective-C-Methoden in Swift. Dies ist das Gegenteil; Swift-Methoden für Objective-C sichtbar machen Die "doSomething" -Methode fehlt einfach in der '-Swift.h'-Datei, wenn sie eine nicht void-Rückgabe hat – Paulw11