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()
}
}
我刚从 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()
}
}