wake-up-neo.net

Xcode 8-Warnung "Instanzmethode entspricht nahezu optionaler Anforderung"

Ich habe mein (macOS) -Projekt in Xcode 8 nach Swift 3 konvertiert und erhalte die folgenden Warnungen mit mehreren Delegat-Methoden, die ich in Swift-Klassen implementiere:

Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'

Ich bekomme dies für mehrere NSApplicationDelegate-Methoden wie applicationDidFinishLaunching und applicationDidBecomeActive:

 enter image description here

Aber auch für Implementierungen von tableViewSelectionDidChange:  enter image description here

 enter image description here

Ich habe die Code-Vervollständigung verwendet, um die Methodensignaturen einzufügen, und versuchte auch, sie aus den SDK-Headern zu kopieren, um Tippfehler auszuschließen. Die Warnungen verschwinden einfach nicht und die Methoden werden nie aufgerufen. 

Was fehlt mir hier?

25
codingFriend1

Wir haben uns mit diesem Problem an den technischen Support von Apple Developer (DTS) gewandt .. __ Sie antworteten, dass dies ein Fehler in XCode 8 sei.

Wir haben einen Fehlerbericht eingereicht und hoffen auf ein schnelles Update. (Apple-Fehlerbericht-ID: 28315920).

Wenn Sie ein ähnliches Problem haben, geben Sie bitte auch Datei einen Fehlerbericht (bezogen auf unseren) an, damit die Apple-Ingenieure keinen einzigen Fall sehen. 


Update für XCode ≥ 8.1

Das Problem scheint jetzt behoben zu sein, zumindest für die Delegat-Methoden, die wir in unserem Projekt verwenden.

25
codingFriend1

Nach stundenlangem Suchen fand ich diese - Swift 3 ObjC Optionale Protokollmethode, die nicht in der Unterklasse aufgerufen wird

Sie können den Fehler umgehen, indem Sie die Funktion-c-Deklaration der Funktion voranstellen

@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
15
MickCrozier

Eine weitere Ursache für diese Warnung, wenn NSError mit Swift verbunden wird:

In Anbetracht dieser Objective-C-Delegatmethode:

- (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;

Das generiert automatisch diese Swift-Methode:

public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)

Die Warnung wurde angezeigt.

In meinem Fall bestand der Grund darin, dass meine Klasse einen eigenen Error-Typ hatte, so dass die Signatur in MyClass.Error statt Swift.Error aufgelöst wurde. Die Lösung bestand darin, den Parameter Error vollständig in Swift.Error einzugeben:

public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
4
Rory O'Bryan

Ein Grund, warum Sie diesen Fehler erhalten könnten, betrifft Modifizierer für den Methodenzugriff. Zum Beispiel, wenn Sie die Funktion nicht als öffentlich definiert haben. Also für Methoden im CLLocationManagerDelegate-Fall:

func locationManager(_ manager: CLLocationManager,
                     didChangeAuthorization status: CLAuthorizationStatus)

zu:

public func locationManager(_ manager: CLLocationManager,
                            didChangeAuthorization status: CLAuthorizationStatus)

(d. h. machen Sie die Methode öffentlich) entfernt die Warnung und die Methode wird wie erwartet aufgerufen. Beachten Sie, dass bei der automatischen Vervollständigung der öffentliche Zugriffsmodifikator nicht für die Methode verwendet wird.

3
DCDC

Für das Protokoll hatte ich das gleiche Problem bei der Implementierung der Delegated-Methode didFailProvisionalNavigation von WKWebView. Die Lösung bestand darin, die @objc-Deklaration und hinzuzufügen und den Typ des letzten Parameters von Error in NSError zu ändern:

@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
    // handle error
}
1
pipacs

Hier ist was für mich behoben.

Ich habe die gleiche Warnung in einem Code erhalten, bei der ich sicher war, dass ich anfangs in den Editor eingegeben und die automatische Vervollständigung zugelassen habe. Anschließend ging ich zurück, um die Warnung erneut aufzurufen, und versuchte, die gleiche Funktion direkt nach meiner bestehenden Funktion erneut einzugeben. Als ich den Funktionsnamen erneut eingab, änderte sich meine Funktionssignatur, und die Parameter stimmten genau mit dem überein, was Xcode erwartete, und die Warnung wurde unterdrückt.

Wenn Sie also eine schnelle Überprüfung des Gesundheitszustandes durchführen möchten, tun Sie sich selbst einen Gefallen und geben Sie die Funktion noch einmal ein. Prüfen Sie, ob sich die Parm-Typen ändern. Das könnte alles sein, was Sie brauchen. 

1
ericdrum

Um dies etwas zu kompliziert zu klären, muss man nur ein wenig komplizierte Problemumgehung hinzufügen: Kann jemand sehen, warum das Folgende nicht abläuft, wenn die Aktion ausgeführt wird?

extension AppDelegate: UNUserNotificationCenterDelegate {
    @objc(userNotificationCenter:didReceiveNotificationResponse:withCompletionHandler:)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("RESPONSE FROM NOTIFICATION!")

        switch response.actionIdentifier {
        case "reply":
            print("Reply action received!")
        case "ignore":
            print("Ignore action received!")
        default: print("Error - Unknown action received!")
            break
        }
    }
}
0
Mark Barrett