Xcode 8 Warning “Instance method nearly matches op

2019-01-14 06:41发布

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:

enter image description here

But also for implementations of tableViewSelectionDidChange: enter image description here

enter image description here

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?

7条回答
女痞
2楼-- · 2019-01-14 06:44

For xcode 8.1 >= and swift 3,

add @nonobjc at the beginning of method to silence this warning.

查看更多
兄弟一词,经得起流年.
3楼-- · 2019-01-14 06:45

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楼-- · 2019-01-14 06:51

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)
查看更多
▲ chillily
5楼-- · 2019-01-14 06:53

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.

查看更多
Rolldiameter
6楼-- · 2019-01-14 07:02

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
}
查看更多
Bombasti
7楼-- · 2019-01-14 07:02

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
        }
    }
}
查看更多
登录 后发表回答