698 Stimmen

@selector() in Swift?

Ich versuche, einen NSTimer in Swift zu erstellen, aber ich habe einige Probleme.

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

test() ist eine Funktion in derselben Klasse.


Ich bekomme einen Fehler im Editor:

Konnte keine Überladung für 'init' finden, die die bereitgestellten Argumente akzeptiert

Wenn ich selector: test() zu selector: nil ändere, verschwindet der Fehler.

Ich habe versucht:

  • selector: test()
  • selector: test
  • selector: Selector(test())

Aber nichts funktioniert und ich kann keine Lösung in den Referenzen finden.

4voto

sschunara Punkte 2265

Bei Verwendung von performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval() Methoden sollte Ihre Methode (die dem Selector entspricht) als

@objc
For Swift 2.0:
    {  
        //...
        self.performSelector(“performMethod”, withObject: nil , afterDelay: 0.5)
        //...

    //...
    btnHome.addTarget(self, action: “buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)
    //...

    //...
     NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector : “timerMethod”, userInfo: nil, repeats: false)
    //...

}

@objc private func performMethod() {
…
}
@objc private func buttonPressed(sender:UIButton){
….
}
@objc private func timerMethod () {
….
}

Für Swift 2.2, muss '#selector()' anstelle von Zeichenfolge und Selektionsname geschrieben werden, damit keine Rechtschreibfehler und Abstürze aufgrund davon mehr auftreten. Hier ein Beispiel:

self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)

3voto

cynistersix Punkte 1215

Ich fand viele dieser Antworten hilfreich, aber es war nicht klar, wie man dies mit etwas machen konnte, das kein Knopf war. Ich habe in Swift einen Gestenrecognizer zu einem UILabel hinzugefügt und hatte Schwierigkeiten, daher ist hier, was für mich funktioniert hat, nachdem ich alles oben gelesen hatte:

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

Wo der "Selector" deklariert wurde als:

func labelTapped(sender: UILabel) { }

Beachten Sie, dass es öffentlich ist und dass ich nicht die Selector() Syntax verwende, aber es ist auch möglich, dies zu tun.

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

3voto

Swift Developer Punkte 247

Die Verwendung von #selector überprüft Ihren Code zur Kompilierzeit, um sicherzustellen, dass die Methode, die Sie aufrufen möchten, tatsächlich existiert. Noch besser: Wenn die Methode nicht existiert, erhalten Sie einen Kompilierfehler: Xcode wird sich weigern, Ihre App zu erstellen, und somit eine weitere mögliche Fehlerquelle ins Nirgendwo verbannen.

override func viewDidLoad() {
        super.viewDidLoad()

        navigationItem.rightBarButtonItem =
            UIBarButtonItem(barButtonSystemItem: .Add, target: self,
                            action: #selector(addNewFireflyRefernce))
    }

    func addNewFireflyReference() {
        gratuitousReferences.append("Fluche deinen plötzlichen, aber unvermeidlichen Verrat!")
    }

3voto

Daxesh Nagar Punkte 1405

Sie erstellen den Selektor wie unten gezeigt.
1.

UIBarButtonItem(
    title: "Ein Titel",
    style: UIBarButtonItemStyle.Done,
    target: self,
    action: "flatButtonPressed"
)
  1. flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

Beachten Sie, dass die @selector-Syntax entfernt wurde und durch einen einfachen String ersetzt wurde, der den zu rufenden Methode benennt. Es gibt einen Bereich, in dem wir alle zustimmen können, dass die Umständlichkeit im Weg stand. Natürlich, wenn wir erklärt haben, dass es eine Zielmethode namens flatButtonPressed: gibt, sollten wir eine schreiben:

func flatButtonPressed(sender: AnyObject) {
  NSLog("flatButtonPressed")
}

setze den Timer:

    var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, 
                    target: self, 
                    selector: Selector("flatButtonPressed"), 
                    userInfo: userInfo, 
                    repeats: true)
    let mainLoop = NSRunLoop.mainRunLoop()  //1
    mainLoop.addTimer(timer, forMode: NSDefaultRunLoopMode) //2 these two lines are optional

Um vollständig zu sein, hier ist der flatButtonPressed

func flatButtonPressed(timer: NSTimer) {
}

2voto

Nathan Day Punkte 5797

Wie viele bereits festgestellt haben, sind Selektoren eine objektive c-Methode zum dynamischen Aufrufen von Methoden, die auf Swift übertragen wurde. In einigen Fällen sind wir immer noch damit beschäftigt, z.B. bei UIKit, wahrscheinlich, weil sie an SwiftUI gearbeitet haben, um es zu ersetzen, aber einige APIs haben eine eher Swift-ähnliche Version, wie z.B. Swift Timer, den man so nutzen kann:

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

Stattdessen kannst du es dann so aufrufen:

Timer.scheduledTimer(withTimeInterval: 1, 
                              repeats: true ) {
    ... dein Testcode hier
}

oder

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

wo die Methode test ein Timer-Argument erhält, oder wenn du möchtest, dass test ein benanntes Argument erhält:

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

Du solltest auch Timer und nicht NSTimer verwenden, da NSTimer der alte objektive-c Name ist.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X