web-dev-qa-db-ja.com

Xcode 8警告「インスタンスメソッドはオプションの要件にほぼ一致します」

Xcode 8で(macOS)プロジェクトをSwift 3に変換し、Swiftクラスで実装するいくつかのデリゲートメソッドで次の警告が表示されます。

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

applicationDidFinishLaunchingapplicationDidBecomeActiveなどのNSApplicationDelegateメソッドでこれを取得します。

enter image description here

しかし、tableViewSelectionDidChangeの実装でも: enter image description here

enter image description here

コード補完を使用してメソッドシグネチャを挿入し、SDKヘッダーからコピーして入力ミスを排除しようとしました。警告は消えず、メソッドは呼び出されません。

ここで何が欠けていますか?

27
codingFriend1

この問題についてApple Developer Technical Support(DTS)に連絡しました。これはXcode 8のバグであると回答しました

バグレポートを提出しましたので、迅速なアップデートを期待しています。 (AppleバグレポートID:28315920)。

同様の問題が発生した場合は、バグレポートを提出してください(私たちのものを参照)Appleエンジニアは、単一のケースではないと考えています。


Xcode≥8.1のアップデート

この問題は、少なくともプロジェクトで使用しているデリゲートメソッドについては、現在修正されているようです。

26
codingFriend1

数時間の検索の後、私はこれを見つけました- サブクラスで呼び出されないSwift 3 ObjCオプションプロトコルメソッド

関数のObjective-C宣言にプレフィックスを付けることでバグを回避できます

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

このエラーが発生する理由の1つは、メソッドアクセス修飾子に関係しています。たとえば、関数をパブリックとして定義しなかった場合。したがって、CLLocationManagerDelegateケースのメソッドの場合、以下を変更します。

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

に:

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

(つまり、メソッドをパブリックにする)は警告を取り除き、メソッドは期待どおりに呼び出されます。オートコンプリートでは、メソッドにパブリックアクセス修飾子が設定されないことに注意してください。

11
DCDC

NSErrorがSwiftにブリッジされているときのこの警告の別の原因:

このObjective-Cデリゲートメソッドを指定すると:

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

これは自動的にこれを生成しますSwift method:

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

警告が表示されました。

私の場合、その理由は、クラスが独自のError型を持っているため、署名がMyClass.ErrorではなくSwift.Errorに解決されたためです。解決策は、ErrorパラメーターをSwift.Errorに変更して完全に入力することでした:

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

記録については、WKWebViewのdidFailProvisionalNavigationデリゲートメソッドを実装するときに同じ問題がありました。解決策は、@ objc宣言を追加することでしたおよび最後のパラメーターのタイプをErrorからNSErrorに変更します。

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

これが私にとってそれを修正したものです。

いくつかのコードで同じ警告が表示されていたので、最初にエディターに入力し、オートコンプリートを許可したと確信していました。その後、戻って警告を再確認し、既存の関数の直後に同じ関数をもう一度入力しようとしました。関数名をもう一度入力すると、関数のシグネチャが変更され、Xcodeが予期したものとパラメーターが正確に一致し、警告が抑制されました。

そのため、簡単な健全性チェックを行いたい場合は、自分で操作を行い、もう一度関数を入力して、parmタイプが変更されるかどうかを確認してください。必要なのはそれだけです。

1
ericdrum

複雑な回避策ではなく、これに明確化を追加するために、アクションが実行されているときに以下が発動/動作しない理由を誰でも見ることができますか?

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