Xcode 8で(macOS)プロジェクトをSwift 3に変換し、Swiftクラスで実装するいくつかのデリゲートメソッドで次の警告が表示されます。
Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'
applicationDidFinishLaunching
やapplicationDidBecomeActive
などのNSApplicationDelegateメソッドでこれを取得します。
しかし、tableViewSelectionDidChange
の実装でも:
コード補完を使用してメソッドシグネチャを挿入し、SDKヘッダーからコピーして入力ミスを排除しようとしました。警告は消えず、メソッドは呼び出されません。
ここで何が欠けていますか?
この問題についてApple Developer Technical Support(DTS)に連絡しました。これはXcode 8のバグであると回答しました 。
バグレポートを提出しましたので、迅速なアップデートを期待しています。 (AppleバグレポートID:28315920)。
同様の問題が発生した場合は、バグレポートを提出してください(私たちのものを参照)Appleエンジニアは、単一のケースではないと考えています。
Xcode≥8.1のアップデート
この問題は、少なくともプロジェクトで使用しているデリゲートメソッドについては、現在修正されているようです。
数時間の検索の後、私はこれを見つけました- サブクラスで呼び出されないSwift 3 ObjCオプションプロトコルメソッド
関数のObjective-C宣言にプレフィックスを付けることでバグを回避できます
@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
このエラーが発生する理由の1つは、メソッドアクセス修飾子に関係しています。たとえば、関数をパブリックとして定義しなかった場合。したがって、CLLocationManagerDelegateケースのメソッドの場合、以下を変更します。
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
に:
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
(つまり、メソッドをパブリックにする)は警告を取り除き、メソッドは期待どおりに呼び出されます。オートコンプリートでは、メソッドにパブリックアクセス修飾子が設定されないことに注意してください。
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!)
記録については、WKWebViewのdidFailProvisionalNavigationデリゲートメソッドを実装するときに同じ問題がありました。解決策は、@ objc宣言を追加することでしたおよび最後のパラメーターのタイプをErrorからNSErrorに変更します。
@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
// handle error
}
これが私にとってそれを修正したものです。
いくつかのコードで同じ警告が表示されていたので、最初にエディターに入力し、オートコンプリートを許可したと確信していました。その後、戻って警告を再確認し、既存の関数の直後に同じ関数をもう一度入力しようとしました。関数名をもう一度入力すると、関数のシグネチャが変更され、Xcodeが予期したものとパラメーターが正確に一致し、警告が抑制されました。
そのため、簡単な健全性チェックを行いたい場合は、自分で操作を行い、もう一度関数を入力して、parmタイプが変更されるかどうかを確認してください。必要なのはそれだけです。
複雑な回避策ではなく、これに明確化を追加するために、アクションが実行されているときに以下が発動/動作しない理由を誰でも見ることができますか?
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
}
}
}