我开始学习Swift,并且一直在关注YouTube上非常好的斯坦福大学的视频讲座。这是一个链接,如果你感兴趣或它有帮助(尽管它不是必须理解我的问题):
使用Swift - 2开发iOS 8应用程序。更多的Xcode和Swift, MVC
在跟随讲座的时候,我得到了一个点(据我所知),我的代码与视频中的代码相同,但在我的系统上,我得到了一个编译器错误。经过大量的尝试和错误,我已经成功地将我的代码减少到两个示例,其中一个生成错误,另一个则不会,但我不知道是什么导致了错误或如何解决它。
产生错误的代码是:
import UIKit
class BugViewController: UIViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
这将创建以下编译器错误:
使用Objective-C选择器'perform: '的方法'perform'与前面使用同一Objective-C选择器的声明冲突
通过简单地删除UIViewController的子类代码编译:
import UIKit
class BugViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
其他一些可能相关或不相关的信息:
我最近升级到约塞米蒂。
当我安装Xcode时,我最终得到了测试版(版本6.3 (6D543q)),因为(如果我没记错的话)这是我在OS X版本上需要运行的版本。
我一半希望这是编译器中的一个bug,否则这对我来说没有任何意义。任何帮助都非常感激!
问题是UIViewController是一个@objc类。从UIViewController继承时,BugViewController也是一个@objc类。
这意味着它必须符合Objective-C选择器的规则(方法的名称)。方法func perform(operation: (Double) -> Double)和func perform(operation: (Double, Double) -> Double)都有相同的选择器@selector(perform:)。这是不允许的。
要解决这个问题,请使用不同的名称:如func perform1(操作:(Double) -> Double)和func perform2(操作:(Double, Double) -> Double)。
我认为最好的处理方法是给你的perform()方法更多描述性的名称。这些方法有什么用?它们如何改变视图控制器的状态?看看其他的UIViewController方法来感受一下方法命名的风格,或者阅读类中的方法名称应该是表达性和唯一性的
问题是UIViewController是一个@objc类。从UIViewController继承时,BugViewController也是一个@objc类。
这意味着它必须符合Objective-C选择器的规则(方法的名称)。方法func perform(operation: (Double) -> Double)和func perform(operation: (Double, Double) -> Double)都有相同的选择器@selector(perform:)。这是不允许的。
要解决这个问题,请使用不同的名称:如func perform1(操作:(Double) -> Double)和func perform2(操作:(Double, Double) -> Double)。
我认为最好的处理方法是给你的perform()方法更多描述性的名称。这些方法有什么用?它们如何改变视图控制器的状态?看看其他的UIViewController方法来感受一下方法命名的风格,或者阅读类中的方法名称应该是表达性和唯一性的
我自己也在上斯坦福的课程,我也被困在这里很长一段时间,但经过一些搜索,我从这里找到了一些东西:Xcode发布说明,它提到了以下内容:
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)
我所做的只是在覆盖方法前面添加“private”,就像这样:
private func performOperation(operation: Double -> Double) {
if operandStack.count >= 1 {
displayValue = operation(operandStack.removeLast())
enter()
}
}