Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
283 views
in Technique[技术] by (71.8m points)

swift - Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector

I am starting to learn Swift, and have been following the very good Stanford University video lectures on YouTube. Here is a link if you are interested or it helps (although it isn't required to understand my problem):

Developing iOS 8 Apps with Swift - 2. More Xcode and Swift, MVC

While following the lectures I got to a point where (as far as I could tell) my code was identical to the code in the video but on my system I got a compiler error. After a lot of trial and error I have managed to reduce my code to two examples, one of which generates an error, the other or which doesn't, but I have no idea what is actually causing the error or how to resolve it.

The code which creates the error is:

import UIKit

class BugViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

This creates the following compiler error:

Method 'perform' with Objective-C selector 'perform: ' conflicts with previous declaration with the same Objective-C selector

By simply removing the sub-classing of UIViewController the code compiles:

import UIKit

class BugViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

Some other information which may or may not be relevant:

  • I have recently upgraded to Yosemite.
  • When I installed Xcode, I ended up with a Beta version (Version 6.3 (6D543q)) because (if I remember correctly) this was the version I needed to run on my version of OS X.

I am half hoping this is a bug in the compiler because otherwise this doesn't make any sense to me. Any help very gratefully received!

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

I myself am also taking the Standford course and I got stuck here for a long time too, but after some searching, I found something from here: Xcode release notes and it mentioned something below:

Swift 1.2 is strict about checking type-based overloading of @objc methods and initializers, something not supported by Objective-C.

// Has the Objective-C selector "performOperation:".
func performOperation(op: NSOperation) { /* do something */ }
// Also has the selector "performOperation:".
func performOperation(fn: () -> Void) {
    self.performOperation(NSBlockOperation(block: fn))
}

This code would work when invoked from Swift, but could easily crash if invoked from Objective-C. To solve this problem, use a type that is not supported by Objective-C to prevent the Swift compiler from exposing the member to the Objective-C runtime:

  • If it makes sense, mark the member as private to disable inference of @objc.
  • Otherwise, use a dummy parameter with a default value, for example: _ nonobjc: () = (). (19826275)

Overrides of methods exposed to Objective-C in private subclasses are not inferred to be @objc, causing the Swift compiler to crash. Explicitly add the @objc attribute to any such overriding methods. (19935352)

Symbols from SDKs are not available when using Open Quickly in a project or workspace that uses Swift. (20349540)

what i did was just adding "private" in front of the override method like this:

    private func performOperation(operation: Double -> Double) {
    if operandStack.count >= 1 {
        displayValue = operation(operandStack.removeLast())
        enter()
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...