【问题标题】:Xcode 8 Warning "Instance method nearly matches optional requirement"Xcode 8 警告“实例方法几乎符合可选要求”
【发布时间】:2017-01-22 13:47:30
【问题描述】:

我在 Xcode 8 中将我的 (macOS) 项目转换为 Swift 3,并在我在 swift 类中实现的几个委托方法中收到以下警告:

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

我通过几个 NSApplicationDelegate 方法得到这个,比如 applicationDidFinishLaunchingapplicationDidBecomeActive

但也适用于tableViewSelectionDidChange 的实现:

我使用代码完成来插入方法签名,并尝试从 SDK 标头中复制它们以排除拼写错误。警告只是不会消失,并且永远不会调用方法。

我在这里错过了什么?

【问题讨论】:

  • 只需将第一种方法的NSNotification 更改为Notification,尽管您的tableViewSelectionDidChange 实现对我来说编译得很好(无警告)。也许尝试清理你的构建文件夹?
  • @Hamish 切换到Notification 没有效果(我相应地调整了问题中的屏幕截图)。我还清理并删除了派生数据文件夹。
  • 我在使用 Swift 教程从 Apple 自己的 iOS 开发中复制并粘贴代码时遇到此错误。在我的情况下,这个信息拯救了我:aplus.rs/2016/… 即,手动输入函数名称并让智能感知提供当前正确的参数。

标签: xcode macos swift3 xcode8


【解决方案1】:

我们就此问题联系了 Apple 开发者技术支持 (DTS)。 他们回答说这是Xcode 8 中的一个错误

我们提交了错误报告并希望快速更新。 (Apple 错误报告 ID:28315920)。

如果您遇到类似问题,也请file a bug report(参考我们的),以便 Apple 工程师看到它不是一个案例。


Xcode ≥ 8.1 更新

现在问题似乎已解决,至少对于我们在项目中使用的委托方法而言。

【讨论】:

  • 完成。 Apple Bug 报告 ID:28383728。忽略警告是否安全?
  • 我的 ID:29691831。多么可怕的错误!从九月开始!我遇到了 XMLParserDelegate 的问题
  • 我已经更新到 xCode 8.2,但我仍然遇到问题 :(
  • 使用 Xcode 9.2 与 application(_:open:options:) 函数有同样的问题...
  • 使用 Xcode 10.1 时,func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? 仍然存在这个问题
【解决方案2】:

经过数小时的搜索,我找到了这个 - Swift 3 ObjC Optional Protocol Method Not Called in Subclass

您可以通过在函数上添加objective-c声明前缀来解决该错误

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

【讨论】:

  • 解决方法有效!警告将保留,但现在可以安全地忽略它,因为该方法将被调用。
  • 该解决方法对 URLSession:task:didCompleteWithError: 方法非常有效,但在 Xcode 8.2.1 中似乎仍然存在问题。
  • 我正在尝试在 xCode 8.3 中使用它,但它不再适用于 URLSession:task:didCompleteWithError,(我收到错误“方法不能标记为 @objc 因为第三个参数的类型不能是用Objective-C表示)。我需要这个回调,有什么想法吗?
  • 这仍然在 Xcode 10.1 中发生,这个解决方法只是帮助我们整个 iOS 团队摆脱困境。
【解决方案3】:

您可能会收到此错误的一个原因与方法访问修饰符有关。例如,如果您没有将函数定义为公共。所以对于 CLLocationManagerDelegate 案例中的方法,改变:

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

到:

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

(即公开方法)消除警告并且按预期调用方法。请注意,自动完成不会将公共访问修饰符放在方法上。

【讨论】:

  • 这应该是公认的答案。这些委托方法中的大多数都是从 objc 调用的,它没有相同的方法访问语义,并且需要public 才能“看到”快速方法实现。
  • 遇到了同样的问题,这解决了它。
  • 这应该是帮助其他人找出答案的公认答案。
【解决方案4】:

NSError 桥接到 Swift 时出现此警告的另一个原因:

鉴于此 Objective-C 委托方法:

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

自动生成这个 Swift 方法:

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

警告已显示。

就我而言,原因是我的班级有自己的Error 类型,因此签名解析为MyClass.Error 而不是Swift.Error。解决方案是通过将错误参数更改为Swift.Error 来完整键入错误参数:

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

【讨论】:

  • 哇,这正是我的问题
【解决方案5】:

对我来说,问题是自定义 Error
基本上我有自己的类,名称为 Error,编译器正在考虑将 delegate method 作为本地方法

我刚刚更改了我自己的班级名称并且它起作用了。因此,只需确认您在函数中没有任何相同的类名

【讨论】:

  • 非常感谢!!您还可以在函数中指定 Swift.Error,以便编译器知道它是 Swift 错误,而不是您定义的自定义错误。这样就不必将您的错误重命名为其他名称。
  • 使用 Swift.Error 我仍然收到警告。不过,更改为 NSError 似乎已经解决了警告。
  • 只要确保函数的参数中没有任何同名的自定义类
【解决方案6】:

作为记录,我在实现 WKWebView 的 didFailProvisionalNavigation 委托方法时遇到了同样的问题。解决方案是添加@objc 声明将最后一个参数的类型从Error更改为NSError:

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

【讨论】:

  • 谢谢!这样可行。不幸的是,它并没有在 xcode 8.0 (8A218a) 中消除对我的警告。
【解决方案7】:

这是为我解决的问题。

我在某些代码中收到了相同的警告,我确信我最初在编辑器中输入并允许它自动完成。随后,我返回并重新查看了警告,并尝试在我现有的函数之后再次键入相同的函数。当我再次输入函数名称时,我的函数签名发生了变化,并且参数与 Xcode 的预期完全匹配,并且警告被抑制了。

因此,如果您想进行快速的健全性检查,请帮自己一个忙,并尝试再次输入该函数,看看参数类型是否发生变化。这可能就是你所需要的。

【讨论】:

    【解决方案8】:

    只是为了澄清这个相当复杂的解决方法:任何人都可以看到为什么在采取行动时下面的内容没有触发/工作?

    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
            }
        }
    }
    

    【讨论】:

    • @codingFriend1 您是否进行了任何更改以使其正常工作或...?非常感谢您的澄清:)
    • 我刚刚改了格式,所以代码显示正确。 (代码必须缩进才能正确格式化)。但是在我的测试中,添加@ objc 并没有使它起作用。我正在等待 Apple 修复它...
    • 绅士——这有什么更新吗?现在 Xcode 8 的正式版已经出来了?我仍然有相同的警告,并且没有调用各种委托方法。
    【解决方案9】:

    这让我转圈圈。这是因为我创建了自己的 Notification 类。一旦我更改了这个类名(不要重构,因为它会改变 objc Notification 参数),所有错误都消失了

    【讨论】:

      【解决方案10】:

      对于 xcode 8.1 >= 和 swift 3,

      在方法的开头添加@nonobjc 以消除此警告。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-27
      • 1970-01-01
      • 2017-12-24
      • 2016-12-22
      • 1970-01-01
      • 1970-01-01
      • 2018-06-23
      相关资源
      最近更新 更多