@selector () w Swift?

659

Próbuję utworzyć NSTimerw, Swiftale mam pewne problemy.

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

test() jest funkcją w tej samej klasie.


W edytorze pojawia się błąd:

Nie można znaleźć przeciążenia dla parametru „init”, które akceptuje podane argumenty

Kiedy przejdę selector: test()do selector: nilbłędu znika.

Próbowałem:

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

Ale nic nie działa i nie mogę znaleźć rozwiązania w referencjach.

Arbitraż
źródło
11
selector: test()wywoła testi przekaże wartość selectorargumentu do argumentu.
Michael Dorst,

Odpowiedzi:

930

Sam Swift nie używa selektorów - kilka wzorców projektowych, które w Objective-C wykorzystują selektory, działa inaczej w Swift. (Na przykład użyj opcjonalnego tworzenia łańcuchów dla typów protokołów lub is/ astestów zamiast respondsToSelector:i używaj zamknięć gdziekolwiek możesz zamiast performSelector:dla lepszego bezpieczeństwa typu / pamięci.)

Ale wciąż istnieje wiele ważnych interfejsów API opartych na ObjC, które używają selektorów, w tym liczniki czasu i wzorzec celu / działania. Swift zapewnia Selectortyp pracy z nimi. (Swift automatycznie wykorzystuje to zamiast typu ObjC SEL.)

W Swift 2.2 (Xcode 7.3) i nowszych (w tym Swift 3 / Xcode 8 i Swift 4 / Xcode 9):

Za Selectorpomocą #selectorwyrażenia można zbudować funkcję typu Swift .

let timer = Timer(timeInterval: 1, target: object,
                  selector: #selector(MyClass.test),
                  userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
                 for: .touchUpInside)
view.perform(#selector(UIView.insertSubview(_:aboveSubview:)),
             with: button, with: otherButton)

Wspaniała rzecz w tym podejściu? Odniesienie funkcja jest sprawdzana przez kompilator Swift, więc można użyć #selectorwyrażenia tylko z parami klasy / metody, które rzeczywiście istnieją i są uprawnione do stosowania jako selektorów (patrz „dostępność Selector” poniżej). Możesz również dowolnie określać odwołania do funkcji tak, jak potrzebujesz, zgodnie z regułami Swift 2.2+ dotyczącymi nazewnictwa typów funkcji .

(Jest to w rzeczywistości ulepszenie w stosunku do @selector()dyrektywy ObjC , ponieważ -Wundeclared-selectorsprawdzenie kompilatora weryfikuje tylko, że istnieje nazwany selektor. Przekazywana funkcja Swift służy do #selectorsprawdzania istnienia, członkostwa w klasie i podpisu typu).

Istnieje kilka dodatkowych zastrzeżeń dotyczących odwołań funkcji przekazywanych do #selectorwyrażenia:

  • Wiele funkcji o tej samej nazwie podstawowej można rozróżnić na podstawie ich etykiet parametrów, stosując wyżej wspomnianą składnię dla odniesień do funkcji (np. insertSubview(_:at:)Vs insertSubview(_:aboveSubview:)). Ale jeśli funkcja nie posiada parametrów, jedynym sposobem, aby go disambiguate jest użycie asobsady z podpisem typu funkcja (np foo as () -> ()vs foo(_:)).
  • W Swift 3.0+ dostępna jest specjalna składnia dla par getter / setter. Na przykład, biorąc pod uwagę a var foo: Int, możesz użyć #selector(getter: MyClass.foo)lub #selector(setter: MyClass.foo).

Ogólne notatki:

Przypadki, w których #selectornie działa i nazywanie: Czasami nie ma odwołania do funkcji, za pomocą którego można by wybrać selektor (na przykład metodami dynamicznie rejestrowanymi w środowisku wykonawczym ObjC). W takim przypadku możesz skonstruować Selectorciąg znaków: np. Selector("dynamicMethod:")- tracisz sprawdzanie poprawności kompilatora. Kiedy to zrobisz, musisz przestrzegać reguł nazewnictwa ObjC, w tym dwukropków ( :) dla każdego parametru.

Dostępność selektora: Metoda, do której odwołuje się selektor, musi być dostępna w środowisku wykonawczym ObjC. W Swift 4 każda metoda narażona na ObjC musi mieć poprzednią deklarację z @objcatrybutem. (W poprzednich wersjach posiadałeś ten atrybut w niektórych przypadkach za darmo, ale teraz musisz go wyraźnie zadeklarować).

Pamiętaj, że privatesymbole również nie są narażone na środowisko uruchomieniowe - twoja metoda musi mieć przynajmniej internalwidoczność.

Kluczowe ścieżki: Są one powiązane, ale niekoniecznie takie same jak selektory. Istnieje również specjalna składnia dla nich w Swift 3: np chris.valueForKeyPath(#keyPath(Person.friends.firstName)). Szczegóły patrz SE-0062 . I jeszcze więcej KeyPathrzeczy w Swift 4 , więc upewnij się, że używasz właściwego interfejsu API opartego na KeyPath zamiast selektorów, jeśli to konieczne.

Możesz przeczytać więcej o selektorach w części Interakcja z interfejsami API Objective-C w Korzystanie z Swift z kakao i Objective-C .

Uwaga: Przed wersją Swift 2.2, SelectorzgodnyStringLiteralConvertible , więc możesz znaleźć stary kod, w którym puste interfejsy są przekazywane do interfejsów API, które pobierają selektory. Będziesz chciał uruchomić „Konwertuj na bieżącą składnię szybkiego” w Xcode, aby uzyskać dostęp do tych #selector.

Rickster
źródło
8
Umieszczenie ciągu z nazwą funkcji działało, NSSelectorFromString () również działa.
Arbitur
7
Chciałbym wspomnieć, że chociaż „Interakcja z interfejsami API Objective-C” znajduje się na stronie internetowej, NIE jest ono w książce „Swift Programming Language”.
10
Powinno to prawdopodobnie wspomnieć, że selektor potrzebuje na końcu „:”, jeśli wymaga argumentu. (Np. Test () -> „test” i test (this: String) -> „test:”)
Daniel Schlaug
2
Należy również zauważyć, że frameworki Cocoa oczekują nazwy metody w stylu Objective-C. Jeśli metoda przyjmuje argument trzeba będzie „:” jeśli trwa 2 argumenty size:andShape:, jeśli pierwszy argument jest nazwany może być potrzebny With, czyli initWithData:zafunc init(Data data: NSData)
JMFR
6
Czy w ogóle można dodać sprawdzanie poprawności wokół przekazywania „selektora” jako ciągu? Kompilator IE ostrzega nas, gdy
popełniamy
86

Oto szybki przykład korzystania z Selectorklasy w Swift:

override func viewDidLoad() {
    super.viewDidLoad()

    var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))
    self.navigationItem.rightBarButtonItem = rightButton
}

func method() {
    // Something cool here   
}

Pamiętaj, że jeśli metoda przekazana jako ciąg znaków nie działa, zakończy się niepowodzeniem w czasie wykonywania, nie skompiluje czasu i zawiesi aplikację. Bądź ostrożny

Oscar Swanros
źródło
13
co jest okropne ... czy istnieje coś takiego jak „NSStringFromSelector”?
Lena Bru
11
nie mogę uwierzyć, że zaprojektowali dla niesprawdzonych selektorów, ponieważ objc miał to
malhal
4
@malcomhall: @selectorjest przydatny, ale nie jest egzekwowany tak formalnie, jak mogłoby się wydawać. „Niezadeklarowany selektor” jest jedynie ostrzeżeniem kompilatora, ponieważ nowe selektory można zawsze wprowadzić w czasie wykonywania. Jednak weryfikowalne / refaktoryzowalne odniesienia selektora w Swift byłyby dobrym żądaniem funkcji .
rickster,
2
Ta odpowiedź jest pomocna, ale odpowiedź poniżej z @objc jest bardziej odpowiednia.
cynistersix
Gdy przekazujesz ciąg selektora jako zmienną lub parametr, musisz poinformować kompilator o jego selektorze za pomocą funkcji Selector (). dzięki
levous
46

Ponadto, jeśli twoja (Swift) klasa nie pochodzi od klasy Objective-C, musisz mieć dwukropek na końcu ciągu nazwy metody docelowej i musisz użyć właściwości @objc z metodą docelową, np.

var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))

@objc func method() {
    // Something cool here   
} 

w przeciwnym razie pojawi się błąd „Unrecognized Selector” w czasie wykonywania.

użytkownik3771857
źródło
3
1. selektory z dwukropkiem muszą przyjąć argument 2. zgodnie z dokumentacją Apple docs działania timera powinny przyjąć argument NSTimer 3. Selectorsłowo kluczowe nie jest obowiązkowe. Więc w tym przypadku podpis musi być@objc func method(timer: NSTimer) {/*code*/}
Jewhen Dubinin
@objcpracował dla mnie. Nie musiałem zawierać timer: NSTimerw metodzie podpisu, aby można go było wywołać.
Mike Taverne
32

Aktualizacja Swift 2.2+ i Swift 3

Użyj nowego #selectorwyrażenia, które eliminuje potrzebę używania literałów łańcuchowych, dzięki czemu użycie jest mniej podatne na błędy. Na przykład:

Selector("keyboardDidHide:")

staje się

#selector(keyboardDidHide(_:))

Zobacz także: Propozycja szybkiej ewolucji

Uwaga (Swift 4.0):

Jeśli używasz #selector, musisz zaznaczyć funkcję jako@objc

Przykład:

@objc func something(_ sender: UIButton)

Kyle Clegg
źródło
26

Swift 4.0

tworzysz Selektor jak poniżej.

1. dodaj wydarzenie do przycisku takiego jak:

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

a funkcja będzie jak poniżej:

@objc func clickedButton(sender: AnyObject) {

}
pravin salame
źródło
4
Zapomniałeś umieścić @objcprzed funcktóra jest wymagana w Swift 4.
Vahida Amirka
24

Dla przyszłych czytelników odkryłem, że napotkałem problem i dostaję unrecognised selector sent to instancebłąd, który został spowodowany przez oznaczenie celu funcjako prywatnego.

func Muszą być dostępne publicznie być wywołana przez obiekt z odniesieniem do selektora.

Rob Sanders
źródło
13
nie musi być publiczny, nadal możesz zachować metodę jako prywatną, ale dodaj objcją przed deklaracją. Np .: @objc private func foo() { ...wtedy możesz użyć "foo"jako selektora, ile chcesz
apouche
Może być również internal, dlatego nie określa żadnego modyfikatora dostępu. Często używam tego wzoru://MARK: - Selector Methods\n extension MyController {\n func buttonPressed(_ button: UIButton) {
Sajjon
19

Na wypadek, gdyby ktoś miał ten sam problem, który miałem z NSTimer, gdzie żadna z pozostałych odpowiedzi nie rozwiązała tego problemu, naprawdę ważne jest, aby wspomnieć, że jeśli używasz klasy, która nie dziedziczy po NSObject bezpośrednio lub głęboko w hierarchii ( np. ręcznie tworzone szybkie pliki), żadna z pozostałych odpowiedzi nie będzie działać, nawet jeśli zostanie określona w następujący sposób:

let timer = NSTimer(timeInterval: 1, target: self, selector: "test", 
                    userInfo: nil, repeats: false)
func test () {}

Nie zmieniając niczego innego niż tylko dziedziczenie klasy od NSObject, przestałem otrzymywać błąd „Nierozpoznany selektor” i logika działała zgodnie z oczekiwaniami.

Martin Cazares
źródło
Problem z tą alternatywą polega na tym, że nie można zmienić klasy (powiedzmy ViewController), aby dziedziczyła po NSObject, biorąc pod uwagę, że potrzebujesz rzeczy zaimplementowanych w klasie ViewController (np. ViewDidLoad ()). Masz pomysł, jak wywołać funkcję Swift w ViewController przy użyciu NSTimer? ... e
eharo2
1
UIViewController już dziedziczy po NSObject, większość klas udostępnianych przez SDK robi, ten przykład dotyczy twoich własnych klas, które wymagają funkcjonalności NSTimer ...
Martin Cazares
14

Jeśli chcesz przekazać parametr do funkcji z NSTimer, oto twoje rozwiązanie:

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)
}

Umieść dwukropek w tekście selektora (tester :), a parametry wejdź w userInfo.

Twoja funkcja powinna przyjmować NSTimer jako parametr. Następnie wystarczy wyodrębnić userInfo, aby uzyskać parametr, który przeszedł.

Skuter
źródło
3
Używałem NSTimer (0.01, target: self, ...), który NIE działał, podczas gdy NSTimer.scheduledTimerWithTimeInterval (0.01, ..) DID działał !? Dziwne, ale dziękuję @ Scooter za odpowiedź!
iOS-Coder,
1
@ iOS-Coder tylko tworzenie timer z initialiser nie dodać go do runloop, natomiast scheduledTimerWith...automatycznie dodaje je do bieżącej runloop - więc nie ma dziwne zachowanie tutaj w ogóle;)
David Ganster
1
@David dzięki za twoją sugestię. Wydaje mi się, że moje nieporozumienie powinno należeć do kategorii STFW lub RTFA (Read The F ... ing API)?
iOS-Coder,
1
Nie martw się tym, nie można oczekiwać, że przeczyta się dokumentację dotyczącą każdej metody w każdym interfejsie API;)
David Ganster,
10

Selektory są wewnętrzną reprezentacją nazwy metody w Objective-C. W Objective-C „@selector (methodName)” konwertuje metodę kodu źródłowego na typ danych SEL. Ponieważ nie możesz użyć składni @selector w Swift (Rickster jest na miejscu), musisz ręcznie określić nazwę metody jako obiekt String lub przekazując obiekt String do typu Selector. Oto przykład:

var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 
    action:"logout"
)

lub

var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 
    action:Selector("logout")
)
Jon Tsiros
źródło
8

Swift 4.1
Z próbką gestu stuknięcia

let gestureRecognizer = UITapGestureRecognizer()
self.view.addGestureRecognizer(gestureRecognizer)
gestureRecognizer.addTarget(self, action: #selector(self.dismiss(completion:)))

// Use destination 'Class Name' directly, if you selector (function) is not in same class.
//gestureRecognizer.addTarget(self, action: #selector(DestinationClass.dismiss(completion:)))


@objc func dismiss(completion: (() -> Void)?) {
      self.dismiss(animated: true, completion: completion)
}

Więcej informacji na temat: wyrażenie selektora znajduje się w dokumencie Apple

Krunal
źródło
Przestańcie to robić. To nikomu nie pomaga. Czym różni się to od Swift 3.1? I dlaczego uważasz, że konieczne jest dodanie kolejnej odpowiedzi na to pytanie, skoro ma już około 20 odpowiedzi?
Fogmeister
selektor wywoływania jest inny w swift 4. Wypróbuj te odpowiedzi w swift 4 i zobacz. Żadne nie będą działać bez edycji. Proszę nie oznaczać żadnego oświadczenia jako spam bez zapewnienia jego impotancji
Krunal
Czy jest więc jakiś powód, dla którego nie mogłeś edytować istniejącej, zaakceptowanej odpowiedzi? Sprawiłoby, że byłoby to rzeczywiście przydatne, zamiast dodawać na końcu długiej listy odpowiedzi. Przycisk „Edytuj” istnieje z jakiegoś powodu.
Fogmeister,
Która część tego różni się od Swift 3?
Fogmeister,
2
Musisz dodać znacznik objc do dowolnych selektorów dla Swift 4. To jest poprawna odpowiedź. I nie powinieneś edytować odpowiedzi innych ludzi, aby zmienić ich znaczenie. @Krunal ma całkowitą rację.
Unome
6
// for swift 2.2
// version 1
buttton.addTarget(self, action: #selector(ViewController.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(ViewController.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 2
buttton.addTarget(self, action: #selector(self.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(self.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 3
buttton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(tappedButton2(_:)), forControlEvents: .TouchUpInside)

func tappedButton() {
  print("tapped")
}

func tappedButton2(sender: UIButton) {
  print("tapped 2")
}

// swift 3.x
button.addTarget(self, action: #selector(tappedButton(_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton) {
  // tapped
}

button.addTarget(self, action: #selector(tappedButton(_:_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton, _ event: UIEvent) {
  // tapped
}
John Lee
źródło
byłoby ładniej i bardziej edukacyjnie, gdybyś miał przykład, biorąc dwa lub trzy argumenty za Swift3 lub Swift4. Dzięki.
nyxee
5
Create Refresh control using Selector method.   
    var refreshCntrl : UIRefreshControl!
    refreshCntrl = UIRefreshControl()
    refreshCntrl.tintColor = UIColor.whiteColor()
    refreshCntrl.attributedTitle = NSAttributedString(string: "Please Wait...")
    refreshCntrl.addTarget(self, action:"refreshControlValueChanged", forControlEvents: UIControlEvents.ValueChanged)
    atableView.addSubview(refreshCntrl)

// Odśwież metodę kontroli

func refreshControlValueChanged(){
    atableView.reloadData()
    refreshCntrl.endRefreshing()

}
Renish Dadhaniya
źródło
5

Ponieważ opublikowano Swift 3.0, jeszcze bardziej subtelne jest zadeklarowanie odpowiedniego parametru targetAction

class MyCustomView : UIView {

    func addTapGestureRecognizer() {

        // the "_" is important
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyCustomView.handleTapGesture(_:)))
        tapGestureRecognizer.numberOfTapsRequired = 1
        addGestureRecognizer(tapGestureRecognizer)
    }

    // since Swift 3.0 this "_" in the method implementation is very important to 
    // let the selector understand the targetAction
    func handleTapGesture(_ tapGesture : UITapGestureRecognizer) {

        if tapGesture.state == .ended {
            print("TapGesture detected")
        }
    }
}
LukeSideWalker
źródło
4

Podczas używania performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval() metody Twoja metoda (pasująca do selektora) powinna być oznaczona jako

@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 () {.
}

W Swift 2.2 musisz napisać „#selector ()” zamiast łańcucha i nazwy selektora, aby nie było już możliwości wystąpienia błędów ortograficznych i awarii. Poniżej znajduje się przykład

self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)
sschunara
źródło
3

tworzysz Selektor jak poniżej.
1.

UIBarButtonItem(
    title: "Some Title",
    style: UIBarButtonItemStyle.Done,
    target: self,
    action: "flatButtonPressed"
)

2)

flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

Zauważ, że składnia @selector zniknęła i została zastąpiona prostym ciągiem nazwującym metodę do wywołania. Jest jeden obszar, w którym wszyscy możemy się zgodzić, że gadatliwość przeszkodzi. Oczywiście, jeśli zadeklarujemy, że istnieje metoda docelowa o nazwie flatButtonPressed: lepiej napisz jedną:

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

ustaw zegar:

    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 this two line is optinal

Aby być kompletnym, oto flatButtonPressed

func flatButtonPressed(timer: NSTimer) {
}
Daxesh Nagar
źródło
Czy masz jakieś źródło „ Zauważ, że nie ma już składni @selector ”?
winklerrr
3

Znalazłem wiele z tych odpowiedzi, które były pomocne, ale nie było jasne, jak to zrobić z czymś, co nie było przyciskiem. Szybko dodawałem rozpoznawanie gestów do UILabel i walczyłem, więc oto, co znalazłem, działało dla mnie po przeczytaniu wszystkiego powyżej:

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

Gdzie „Selektor” został zadeklarowany jako:

func labelTapped(sender: UILabel) { }

Zauważ, że jest to publiczne i że nie używam składni Selector (), ale można to również zrobić.

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: Selector("labelTapped:"))
cynistersix
źródło
3

Użycie #selector sprawdzi kod w czasie kompilacji, aby upewnić się, że metoda, którą chcesz wywołać, faktycznie istnieje. Co więcej, jeśli metoda nie istnieje, pojawi się błąd kompilacji: Xcode odmówi zbudowania Twojej aplikacji, tym samym zakazując zapomnienia o innym możliwym źródle błędów.

override func viewDidLoad() {
        super.viewDidLoad()

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

    func addNewFireflyReference() {
        gratuitousReferences.append("Curse your sudden but inevitable betrayal!")
    }
Swift Developer
źródło
2

Przydatne może być zwrócenie uwagi na to, gdzie skonfigurowano element sterujący, który wyzwala działanie.

Na przykład odkryłem, że podczas konfigurowania UIBarButtonItem musiałem utworzyć przycisk w ramach viewDidLoad, inaczej dostałbym nierozpoznany wyjątek selektora.

override func viewDidLoad() {
    super.viewDidLoad() 

    // add button
    let addButton = UIBarButtonItem(image: UIImage(named: "746-plus-circle.png"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("addAction:"))
    self.navigationItem.rightBarButtonItem = addButton
}

func addAction(send: AnyObject?) {     
    NSLog("addAction")
}
Michael Peterson
źródło
1

Zmień jako prosty ciąg nazewnictwa w metodzie wywołującej składnię selektora

var timer1 : NSTimer? = nil
timer1= NSTimer(timeInterval: 0.1, target: self, selector: Selector("test"), userInfo: nil, repeats: true)

Następnie wpisz func test ().

Thar Htet
źródło
1

selectorto słowo ze Objective-Cświata i możesz z niego korzystać, Swiftaby mieć możliwość dzwonienia Objective-Cz niego. Swift Pozwala na wykonanie kodu w czasie wykonywania

Przed Swift 2.2składnią jest:

Selector("foo:")

Ponieważ nazwa funkcji jest przekazywana Selectorjako parametr String („foo”), nie można sprawdzić nazwy w czasie kompilacji . W rezultacie ty może dostać błąd wykonania:

unrecognized selector sent to instance

Po Swift 2.2+składni jest:

#selector(foo(_:))

Autouzupełnianie Xcode pomaga ci wybrać odpowiednią metodę

yoAlex5
źródło
0

Dla Swift 3

// Przykładowy kod do utworzenia timera

Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)

WHERE
timeInterval:- Interval in which timer should fire like 1s, 10s, 100s etc. [Its value is in secs]
target:- function which pointed to class. So here I am pointing to current class.
selector:- function that will execute when timer fires.

func updateTimer(){
    //Implemetation 
} 

repeats:- true/false specifies that timer should call again n again.
CrazyPro007
źródło
0

Selektor w Swift 4:

button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside)
Mahesh Chaudhari
źródło
-1

Dla szybkiego 3

let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.test), userInfo: nil, repeats: true)

Deklaracja funkcji W tej samej klasie:

@objc func test()
{
    // my function
} 
Mustajab Haider
źródło
Jeśli cel jest własny, nie ma potrzeby selfwyboru w selektorze. To powinno wystarczyć:let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(test), userInfo: nil, repeats: true)
Mithra Singam,