Compiler error: Method with Objective-C selector conflicts with previous declaration with the same Objective-C selector
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()
}
}
Objective-C does not support method overloading, you have to use a different method name. When you inherited UIViewController you inherited NSObject and made the class interopable to Obj-C. Swift on the other hand does support overloading, that's why it works when you remove the inheritance.
As it has already been answered, ObjC doesn't support method overloading (two methods with the same name) and In swift 2 under Xcode 7 there are two options to solve this kind of problems. One option is to rename the method using the attribute: @objc(newNameMethod:)
func methodOne(par1, par2) {...}
@objc(methodTwo:)
func methodOne(par1) {...}
another option to solve this problem in Xcode 7+ is by applying @nonobjc
attribute to any method, subscript or initialiser
func methodOne() {...}
@nonobjc
func methodOne() {...}
The problem is UIViewController
is an @objc
class. When inheriting from UIViewController
, BugViewController
is also a @objc
class.
This means it must conform to the rules of Objective-C selectors (the name of a method). The methods func perform(operation: (Double) -> Double)
and func perform(operation: (Double, Double) -> Double)
both have the same selector @selector(perform:)
. This is not allowed.
To resolve this, use different names: like func perform1(operation: (Double) -> Double)
and func perform2(operation: (Double, Double) -> Double)
.
I think the best way to handle this is to give your perform()
methods more descriptive names. What do these methods do? How do they change the state of the view controller? Look at the other UIViewController
methods to get a feel for the style of method naming, or read Method Names Should Be Expressive and Unique Within a Class