Xcode 8 个警告 "Instance method nearly matches optional requirement"
Xcode 8 Warning "Instance method nearly matches optional requirement"
我在 Xcode 8 中将我的 (macOS) 项目转换为 Swift 3 并且我在 swift 类 中实现的几个委托方法收到以下警告:
Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'
我为几个 NSApplicationDelegate 方法得到了这个,比如 applicationDidFinishLaunching
和 applicationDidBecomeActive
:
但也适用于 tableViewSelectionDidChange
的实现:
我使用代码完成来插入方法签名,并尝试从 SDK-headers 中复制它们以排除拼写错误。警告不会消失,也不会调用这些方法。
我在这里错过了什么?
我们就此问题联系了 Apple 开发人员技术支持 (DTS)。
他们回答说这是 Xcode 8. 中的一个 错误。
我们提交了错误报告,希望尽快更新。 (Apple 错误报告 ID:28315920)。
如果您遇到类似问题,还请file a bug report(指我们的),以便苹果工程师看到它不是一个案例。
更新 Xcode ≥ 8.1
问题现在似乎已解决,至少对于我们在项目中使用的委托方法而言是这样。
经过几个小时的搜索,我找到了这个 -
您可以通过在函数
的 objective-c 声明前加上前缀来解决此错误
@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
郑重声明,我在实现 WKWebView 的 didFailProvisionalNavigation 委托方法时遇到了同样的问题。解决方案是添加@objc 声明 and 将最后一个参数的类型从 Error 更改为 NSError:
@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
// handle error
}
只是为了澄清这个过于复杂的解决方法:有人能看出为什么在执行操作时下面的内容不是 firing/working 吗?
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
}
}
}
对于 xcode 8.1 >= 和 swift 3,
在方法的开头添加@nonobjc 以消除此警告。
当 NSError
桥接到 Swift 时出现此警告的另一个原因:
鉴于此 Objective-C 委托方法:
- (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;
自动生成这个Swift方法:
public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)
已显示警告。
在我的例子中,原因是我的 class 有自己的 Error
类型,所以签名解析为 MyClass.Error
而不是 Swift.Error
。解决方案是通过将错误参数更改为 Swift.Error
:
来完全键入错误参数
public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
这是为我修复的。
我在某些代码中收到了相同的警告,我确定我最初在编辑器中输入并允许它自动完成。随后,我返回并重新查看警告,并尝试在我现有的函数之后再次键入相同的函数。当我再次输入函数名称时,我的函数签名发生了变化并且参数与 Xcode 预期的完全匹配并且警告被抑制了。
因此,如果您想快速进行完整性检查,请帮自己一个忙,再尝试输入一次该函数,看看参数类型是否发生变化。这可能就是你所需要的。
您可能会收到此错误的一个原因与方法访问修饰符有关。例如,如果您没有将函数定义为 public。因此,对于 CLLocationManagerDelegate 案例中的方法,更改:
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
至:
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
(即使方法 public)消除警告并按预期调用该方法。请注意,自动完成不会在方法上放置 public 访问修饰符。
对我来说问题是自定义的 Error
class
基本上我有自己的 class 名称 Error
并且编译器正在考虑 delegate method
作为本地方法
我刚刚更改了我自己的 class 名字,它成功了。因此,只需确认您在函数
中没有任何 class 名称相同
这让我原地转了一圈。这是因为我创建了自己的 Notification class。一旦我更改了这个 class 名称(不要重构,因为它会更改 objc 通知参数),所有错误都消失了
我在 Xcode 8 中将我的 (macOS) 项目转换为 Swift 3 并且我在 swift 类 中实现的几个委托方法收到以下警告:
Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'
我为几个 NSApplicationDelegate 方法得到了这个,比如 applicationDidFinishLaunching
和 applicationDidBecomeActive
:
但也适用于 tableViewSelectionDidChange
的实现:
我使用代码完成来插入方法签名,并尝试从 SDK-headers 中复制它们以排除拼写错误。警告不会消失,也不会调用这些方法。
我在这里错过了什么?
我们就此问题联系了 Apple 开发人员技术支持 (DTS)。 他们回答说这是 Xcode 8. 中的一个 错误。
我们提交了错误报告,希望尽快更新。 (Apple 错误报告 ID:28315920)。
如果您遇到类似问题,还请file a bug report(指我们的),以便苹果工程师看到它不是一个案例。
更新 Xcode ≥ 8.1
问题现在似乎已解决,至少对于我们在项目中使用的委托方法而言是这样。
经过几个小时的搜索,我找到了这个 -
您可以通过在函数
的 objective-c 声明前加上前缀来解决此错误@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
郑重声明,我在实现 WKWebView 的 didFailProvisionalNavigation 委托方法时遇到了同样的问题。解决方案是添加@objc 声明 and 将最后一个参数的类型从 Error 更改为 NSError:
@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
// handle error
}
只是为了澄清这个过于复杂的解决方法:有人能看出为什么在执行操作时下面的内容不是 firing/working 吗?
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
}
}
}
对于 xcode 8.1 >= 和 swift 3,
在方法的开头添加@nonobjc 以消除此警告。
当 NSError
桥接到 Swift 时出现此警告的另一个原因:
鉴于此 Objective-C 委托方法:
- (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;
自动生成这个Swift方法:
public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)
已显示警告。
在我的例子中,原因是我的 class 有自己的 Error
类型,所以签名解析为 MyClass.Error
而不是 Swift.Error
。解决方案是通过将错误参数更改为 Swift.Error
:
public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
这是为我修复的。
我在某些代码中收到了相同的警告,我确定我最初在编辑器中输入并允许它自动完成。随后,我返回并重新查看警告,并尝试在我现有的函数之后再次键入相同的函数。当我再次输入函数名称时,我的函数签名发生了变化并且参数与 Xcode 预期的完全匹配并且警告被抑制了。
因此,如果您想快速进行完整性检查,请帮自己一个忙,再尝试输入一次该函数,看看参数类型是否发生变化。这可能就是你所需要的。
您可能会收到此错误的一个原因与方法访问修饰符有关。例如,如果您没有将函数定义为 public。因此,对于 CLLocationManagerDelegate 案例中的方法,更改:
func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
至:
public func locationManager(_ manager: CLLocationManager,
didChangeAuthorization status: CLAuthorizationStatus)
(即使方法 public)消除警告并按预期调用该方法。请注意,自动完成不会在方法上放置 public 访问修饰符。
对我来说问题是自定义的 Error
class
基本上我有自己的 class 名称 Error
并且编译器正在考虑 delegate method
作为本地方法
我刚刚更改了我自己的 class 名字,它成功了。因此,只需确认您在函数
中没有任何 class 名称相同这让我原地转了一圈。这是因为我创建了自己的 Notification class。一旦我更改了这个 class 名称(不要重构,因为它会更改 objc 通知参数),所有错误都消失了