Swift 1.2 重新声明 Objective-C 方法

Swift 1.2 redeclares Objective-C method

我刚从 swift 1.1 更新到 swift 1.2 并得到编译器错误:

Method 'setVacation' redeclares Objective-C method 'setVacation:'

这里是一些代码:

var vacation : Vacation?  
func setVacation(_vacation : Vacation)
{...}

但是我需要打电话 setVacation

有什么解决办法的建议吗?

这是由 Xcode 6.3beta 发行说明中所述的更改引起的:

Swift now detects discrepancies between overloading and overriding in the Swift type system and the effective behavior seen via the Objective-C runtime. (18391046, 18383574) For example, the following conflict between the Objective-C setter for “property” in a class and the method “setProperty” in its extension is now diagnosed:

 class A : NSObject {
     var property: String = "Hello" // note: Objective-C method 'setProperty:’
                                    // previously declared by setter for
                                    // 'property’ here
 }
 extension A {
     func setProperty(str: String) { } // error: method ‘setProperty’
                                       // redeclares Objective-C method
                                       //'setProperty:’
 }

要解决此问题,您需要使所有方法签名都是唯一的(因为 Objective-C 不提供方法重载)

或者如果您只需要 Swift,则不要继承 NSObject class。

正如@Kirsteins 所指出的,Swift 现在可以检测到 Swift 和 Obj-C 之间的冲突符号,以及 swift 会导致 Obj-C 崩溃的符号。除了给出的答案之外,您通常可以通过为其他类型指定所需的标签来避免这种情况,从而更改调用签名:

import Foundation

extension NSObject {
    func foo(d:Double, i:Int) { println("\(d), \(i)") }
    func foo(withInt d:Int, i:Int) { println("\(d), \(i)") }
}

let no = NSObject()
no.foo(withInt:1, i: 2)

除此之外,为了回答您的直接问题,您正在尝试将 Obj-C 习语应用于 Swift。你真正想要的是实现 didSet (最有可能),或者可能 set:

class WhatIDidLastSummer {

    var vacation:Bool = false {
        didSet {
            // do something
        }
    }

    var staycation:Bool {
        get { return true }
        set {
            // do something
        }
    }

}

Cappy:对于 Standford 问题,我简单地使用了这个,因为看起来 Xcode Beta 只是说操作:(Double, Double) -> Double 与操作相同:Double -> double,不知道是不是bug...

但是下面的代码有效,但是干净:(

func performOperation(r:String? = "2", operation: (Double, Double) -> Double) {
    if operandStack.count >= 2 {
        displayValue = operation(operandStack.removeLast(), operandStack.removeLast())
        enter()
    }
}

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