我试图在Swift中创建一个NSTimer,但我遇到了一些麻烦。

NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)

Test()是同一个类中的一个函数。


我在编辑器中得到一个错误:

无法找到一个超载的'init'接受提供的 参数

当我把selector: test()改为selector: nil时,错误就消失了。

我试过了:

选择器:测试() 选择器:测试 选择器:选择器(测试())

但是什么都没用,我在参考文献中找不到解决方案。


当前回答

我发现很多答案都很有用,但我不清楚如何用一个不是按钮的东西来做到这一点。我在swift中添加了一个手势识别器到UILabel中,所以在阅读以上所有内容后,我发现以下是对我有用的:

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: "labelTapped:")

其中“Selector”被声明为:

func labelTapped(sender: UILabel) { }

请注意,它是公共的,我没有使用Selector()语法,但也可以这样做。

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: Selector("labelTapped:"))

其他回答

正如许多人所说,选择器是一种动态调用方法的objective - c方式,已经被带到了Swift中,在某些情况下我们仍然坚持使用它,比如UIKit,可能是因为他们在SwiftUI上工作来取代它,但一些api有更Swift的版本,比如Swift Timer,例如你可以使用

class func scheduledTimer(withTimeInterval interval: TimeInterval, 
                                            repeats: Bool, 
                                              block: @escaping (Timer) -> Void) -> Timer

相反,你可以这样称呼它

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true ) {
    ... your test code here
}

or

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true,
                              block: test)

方法test需要一个Timer参数,或者如果你想test需要一个命名参数

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true,
                              block: test(timer:))

你也应该使用Timer而不是NSTimer因为NSTimer是objective-c的旧名字

如果你想从NSTimer中传递一个参数给函数,那么这里是你的解决方案:

var somethingToPass = "It worked"

let timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "tester:", userInfo: somethingToPass, repeats: false)

func tester(timer: NSTimer)
{
    let theStringToPrint = timer.userInfo as String
    println(theStringToPrint)
}

在选择器文本(tester:)中包含冒号,参数则放在userInfo中。

你的函数应该以NSTimer作为参数。然后提取userInfo以获得传递的参数。

Swift 2.2+和Swift 3更新

使用新的#selector表达式,它消除了使用字符串文字的需要,使使用更不容易出错。供参考:

Selector("keyboardDidHide:")

就变成了

#selector(keyboardDidHide(_:))

参见:快速进化提案

注意(Swift 4.0):

如果使用# selector,你需要将函数标记为@objc

例子:

@objc func something(_ sender: UIButton)

objective - c选择器

Selector标识一个方法。

//Compile time
SEL selector = @selector(foo);

//Runtime
SEL selector = NSSelectorFromString(@"foo");

例如

[object sayHello:@"Hello World"];
//sayHello: is a selector

selector是一个来自Objective-C世界的词,你可以从Swift中使用它,有可能从Swift中调用Objective-C,它允许你在运行时执行一些代码

在Swift 2.2之前,语法是:

Selector("foo:")

因为函数名是作为字符串参数("foo")传入Selector的,所以在编译时不可能检查名称。结果你会得到一个运行时错误:

unrecognized selector sent to instance

在Swift 2.2+之后,语法是:

#selector(foo(_:))

Xcode的自动完成功能帮助你调用正确的方法

选择器在Swift 4:

button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside)