可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I converted my (macOS) project to Swift 3 in Xcode 8 and I get the following warnings with several delegate methods I implement in swift classes:
Instance method 'someMethod' nearly matches optional requirement of protocol 'protocolName'
I get this for several NSApplicationDelegate methods like applicationDidFinishLaunching
and applicationDidBecomeActive
:
But also for implementations of tableViewSelectionDidChange
:
I used code completion to insert the method signatures and also tried copying them from the SDK-headers to rule out typos. The warnings just don't disappear and the methods are never called.
What am I missing here?
回答1:
We contacted Apple Developer Technical Support (DTS) with this issue.
They replied that this is a bug in XCode 8.
We submitted a bug report and hope for a quick update. (Apple Bug Report ID: 28315920).
If you experience a similar issue, please also file a bug report (referring to ours) so the Apple engineers see its not a single case.
Update for XCode ≥ 8.1
The problem seems fixed now, at least for the delegate methods we are using in our project.
回答2:
After hours of searching I found this - Swift 3 ObjC Optional Protocol Method Not Called in Subclass
You can workaround the bug by prefixing the objective-c declaration on the function
@objc(tableViewSettingsDidChange:notification:)
func tableViewSettingsDidChange(_ notification:Notification)
回答3:
Another cause of this warning when NSError
is being bridged to Swift:
Given this Objective-C delegate method:
- (void)myService:(id<MYService>)myService didFailForSomeReason:(NSError *)error;
That automatically generates this Swift method:
public func myService(_ myService: MYService!, didFailForSomeReason error: Error!)
The warning was shown.
In my case the reason was that my class had it's own Error
type so the signature was resolving to MyClass.Error
rather than Swift.Error
. The solution was to fully type the Error parameter by changing it to Swift.Error
:
public func myService(_ myService: MYService!, didFailForSomeReason error: Swift.Error!)
回答4:
For the record, I had the same problem when implementing WKWebView's didFailProvisionalNavigation delegate method. The solution was to add the @objc declaration and change the type of the last parameter from Error to NSError:
@objc(webView:didFailProvisionalNavigation:withError:)
func webView(_ webView: WKWebView, didFailProvisionalNavigation navigation: WKNavigation!, withError error: NSError) {
// handle error
}
回答5:
Here's what fixed it for me.
I was getting the same warning in some code that I was sure that I typed into the editor initially and allowed it to autocomplete. I subsequently went back and re-visted the warning and tried to just type the same function over again right after my existing function. When I entered the function name over again, my function signature changed and the parms matched up exactly with what Xcode expected and the warning was suppressed.
So if you want to do a quick sanity check, do yourself a favor and try typing in the function one more time and see if the parm types change. That might be all you need.
回答6:
Just to add clarification to this rather over complicated workaround: can anyone see why the below is not firing/working when the action is being taken?
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
}
}
}
回答7:
For xcode 8.1 >= and swift 3,
add @nonobjc at the beginning of method to silence this warning.