Swift-da @selector ()

Swift NSTimer yaratmağa çalışıram, amma problemlərim var.

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

test() eyni sinifdə bir funksiyadır.


Redaktorda bir səhv alıram:

Verilən Arqumentləri qəbul edən "init" üçün yüklənmə tapıla bilmədi

selector: test() dəyişdirəndə selector: test() selector: nil , səhv olur.

Mən çalışdım:

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

Amma heç bir şey işləmir və əlaqələrdə həll tapa bilmirəm.

608
03 июня '14 в 8:21 2014-06-03 08:21 Arbitur 3 İyun , '14 'də 8:21' də təyin olunur 2014-06-03 08:21
@ 22 cavab

Swift özü seçicilərdən istifadə etmir - Objective-C seçicilərindən istifadə edən bir sıra dizayn nümunələri Swift-də fərqli şəkildə işləyir. (Məsələn, protokol tipləri üçün isteğe bağlı bir zəncir istifadə edin və ya performSelector: əvəzinə / yerinə performSelector: yerinə, yerinə yetirmək üçün sıx istifadə edin performSelector: növü və yaddaş təhlükəsizliyini artırmaq üçün.

Amma seçicilərdən istifadə edən daha çox əhəmiyyətli ObjC-based API var, o cümlədən taymerlər və hədəf / hərəkət nümunəsi. Swift, onlarla işləyən bir Selector növü təmin edir. (Swift avtomatik ObjC SEL əvəzinə bunu istifadə edir).

Swift 2.2 (Xcode 7.3) və daha sonra (Swift 3 / Xcode 8 və Swift 4 / Xcode 9 daxil olmaqla):

# Selector ifadəsini istifadə edərək, Swift funksiyasından bir Selector qura bilərsiniz.

 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) 

Bu yanaşma haqqında böyük bir şey? Funksiya istinadları Swift kompilyatoru tərəfindən yoxlanılır, belə ki, #selector ifadəsini yalnız mövcud olan və seçicilər kimi istifadə edilə bilən sinif / metod cütləri ilə istifadə edə bilərsiniz (bax "Əliliyət Seçimi" altında). Funksional linkinizə yalnız Swift 2.2 + funksional növlərin adlandırılması qaydalarına əsasən sərbəst şəkildə keçid edə bilərsiniz.

(Bu, həqiqətən, ObjC @selector() direktivi üzərində bir inkişafdır, çünki -Wundeclared-selector compiler yalnız seçilmiş selektorun olduğunu yoxlayır.Sizin varlığınıza, sinif üzvlüyünə və tipinə daxil olan # #selector yoxlamalara keçən Swift funksiyasına keçid.

#selector ifadəsinə keçdiyiniz funksiyalara istinad üçün bir neçə əlavə sifariş var:

  • Eyni əsas adı ilə bir neçə funksiya funksiyası istinadları üçün yuxarıda göstərilən sözdizimləri (məsələn, insertSubview(_:at:) və ya insertSubview(_:aboveSubview:) ) istifadə edərək parametr yazıları ilə fərqləndirilə bilər. Funksiyanın parametrləri yoxdursa, onu aradan qaldırmanın yeganə yolu bir funksiya növü imza ilə (məsələn, foo as () -> () vs foo(_:) ) döküm as istifadə etməkdir.
  • Swift 3.0+, getter / setter cütləri üçün xüsusi bir sintaksis var. Məsələn, #selector(getter: MyClass.foo) var foo: Int #selector(getter: MyClass.foo) və ya #selector(setter: MyClass.foo) istifadə edə bilərsiniz.

Ümumi Qeydlər:

#selector işləməyən və adları olan hallar: Bəzən bir seçici etmək üçün funksiya #selector malik deyilsiniz (məsələn, ObjC işləmə müddətində dinamik qaydada istifadə edilən üsullardan istifadə edirsiniz) Bu halda, Selektorunu simadan qura bilərsiniz: məsələn . Selector("dynamicMethod:") - kompilyatorun təsdiqini itirmiş olmasına baxmayaraq. Bunu etdiyiniz zaman, ObjC adlandırma konvensiyalarını, o cümlədən hər bir parametr üçün colons ( : daxil etməlisiniz.

Selector Erişilebilirlik: Selektor tərəfindən istinad üsulu ObjC icrası zamanı açılmalıdır. Swift 4-də, ObjC-ə məruz qalan hər bir metod @objc xüsusiyyətindən əvvəl öz bəyannaməsinə malik olmalıdır. (Əvvəlki versiyalarda, bəzi hallarda bu xüsusiyyətləri pulsuz qəbul etdiniz, amma indi açıq şəkildə bəyan etməliyik.)

private simvolların iş vaxtında göstərilmədiyini unutmayın - metodunuz ən az internal görünürlüğüne malik olmalıdır.

Açar yolları: Seçicilərlə əlaqəli, lakin eyni deyil. Swift 3-də onlar üçün xüsusi bir sintaksis var: məsələn. chris.valueForKeyPath(#keyPath(Person.friends.firstName)) . Ətraflı məlumat üçün SE-0062- ə baxın. Və Swift 4- də daha çox KeyPath məhsulları , belə ki, zəruri hallarda seçicilərin yerinə sağ KeyPath əsaslı API istifadə etdiyinizdən əmin olun.

Seçicilər haqqında daha ətraflı məlumat üçün, Swift Kakao və Objective-C ilə Objective-C API'larla əlaqə saxlayın .

Qeyd . Swift 2.2-dən əvvəl Selector StringLiteralConvertible ilə StringLiteralConvertible , çılpaq xətlərin selektoru qəbul edən API- StringLiteralConvertible köhnə kodu tapa bilərsiniz. #selector istifadə edənləri əldə etmək üçün Xcode-də "Mövcud Swift sintaksisinə keçmək" işlətmək #selector .

886
03 июня '14 в 8:27 2014-06-03 08:27 cavab iyun ayının 03-də saat 08: 27 -də verilir

Swift-da Selector sınıfını istifadə etmək üçün qısa bir nümunə:

 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 } 
border=0

Dəmir kimi işlədilən metod işləməyəcəksə, iş vaxtında işləməyəcək, ancaq kompilyasiya vaxtı və tətbiqinizin çökməyəcəyini unutmayın. Diqqətli olun.

78
03 июня '14 в 8:31 2014-06-03 08:31 Cavab Oscar Swanros tərəfindən 03 iyun 'da saat 8: 31 -də verilir 2014-06-03 08:31

Bundan əlavə, əgər (Swift) sinfi Objective-C sinifindən silinməsə, hədəf metodunun adının simasının sonunda bir ikiqat olmalıdır və @objc obyektini hedef metodunuzla istifadə etməlisiniz, məsələn,

 var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method")) @objc func method() { // Something cool here } 

əks halda iş vaxtında "Tanınmayan selektor" səhv mesajı alacaqsınız.

44
24 июня '14 в 18:23 2014-06-24 18:23 cavab user3771857 24 iyun 'da 18:23' də verilir 2014-06-24 18:23

Swift 2. 2 + və Swift 3 Update

İstifadədən daha az səhv meylli edən #selector istifadə etmək ehtiyacını aradan #selector yeni ifadəni istifadə edin. Müraciət üçün:

 Selector("keyboardDidHide:") 

olur

 #selector(keyboardDidHide(_:)) 

Həmçinin baxın: Swift Evolution təklifi

Qeyd (Swift 4.0):

#selector istifadə #selector funksiyanı @objc kimi qeyd etmək lazımdır

Məsələn:

@objc func something(_ sender: UIButton)

24
06 апр. Cavab Kyle Clegg Apr 06 2016-04-06 19:06 '16 at 07:06 pm 2016-04-06 19:06

Gələcək oxucular üçün mən bir çətinlik yaşandığımı və func hədəfinin bağlanıldığından qaynaqlanan səhv səhv unrecognised selector sent to instance olduğunu anladım.

func , selektorun istinad etdiyi bir obyekt tərəfindən çağırılmaq üçün ictimaiyyətə açıq olmalıdır .

23
10 апр. Rob Sanders tərəfindən 10 Apreldə cavab verildi 2015-04-10 21:08 '15 at 21:08 2015-04-10 21:08

Yalnız bir başqasının eyni problemi olsaydı, NSTimer ilə qarşılaşdım, digər cavabların heç biri problemi həll etmədikdə, NSObject'i birbaşa və ya hiyerarşiyə dərindən devralmayan bir sinifdən istifadə etdiyinizə diqqət yetirin məsələn, əl ilə yaradılan sürətli fayllar), digər cavabların heç biri işləməyəcəkdir, hətta aşağıdakı kimi müəyyən edilir:

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

NSObject-dən bir sinifin devralmasından başqa bir şeyi dəyişdirmədən, "Tanınmayan selektor" səhvini almağa getdim və gözlənildiyi kimi məntiqi işimi aldım.

19
13 июля '14 в 8:31 2014-07-13 08:31 Cavab Martin Cazares tərəfindən 13 İyul '14 'də saat 08:31 ' də veriləcək

Swift 4.0

Aşağıda göstərildiyi kimi bir selektor yaratmaq.

1. düyməyə bir hadisə əlavə edin:

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

funksiyası aşağıdakı kimi olacaq:

 @objc func clickedButton(sender: AnyObject) { } 
18
15 окт. Cavab 15 oktyabrda pravin salamı verilir . 2014-10-15 10:27 '14 at 10:27 2014-10-15 10:27

NSTimer-dən funksiya parametrini keçirmək istəyirsinizsə, burada sizin həlliniz:

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

Sütun mətnində (testçi :) kolon daxil edin və parametrlər userInfo-da daxil edilir.

Parametr olaraq funksiyanız NSTimer qəbul etməlidir. Sonra keçmiş parametri almaq üçün sadəcə userInfo qəbul edin.

14
07 авг. Scooter 07 Avqust cavab verdi 2014-08-07 18:29 '14 at 18:29 2014-08-07 18:29

Seçicilər Objective-C-də metod adının daxili təmsilçisidir. Objective-C'de "@selector (methodName)" bir qaynaq kodunu SEL data növünə çevirir. Swift'daki @selector sözdizimini (burada rickster) istifadə edə bilmədiyindən, metod adını bir String obyekti olaraq əl ilə göstərməlisiniz və ya String obyektini Selector növünə keçməlisiniz. Burada bir nümunə:

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

və ya

 var rightBarButton = UIBarButtonItem( title: "Logout", style: UIBarButtonItemStyle.Plain, target: self, action:Selector("logout") ) 
10
05 июня '14 в 8:43 2014-06-05 08:43 Cavab Jon Tsiros tərəfindən 05 iyun 'da saat 08:43 ' də verildi. 2014-06-05 08:43

Swift 4.1
Vinç jestinin nümunəsi ilə

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

Daha ətraflı məlumat üçün Apple sənədinə baxın: selektor ifadə

8
09 июня '17 в 16:43 2017-06-09 16:43 Cavab Krunal tərəfindən 09 iyun '16' da 16:43 2017-06-09 16:43 'də verilir
 // 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 } 
6
01 июня '16 в 6:42 2016-06-01 06:42 cavab 01 iyun '16' da 6:42 2016-06-01 06:42 ' də John Lee tərəfindən verilir

Swift 3.0 nəşr olunduğundan, uyğun bir hədəf istiqamətini elan etmək üçün bir qədər incədir.

 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") } } } 
5
16 сент. LukeSideWalker 16 sentyabr tarixində göndərilib 2016-09-16 21:24 '16 'da 21:24 2016-09-16 21:24' də
 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) 

// Güncelleme nəzarət metodu

 func refreshControlValueChanged(){ atableView.reloadData() refreshCntrl.endRefreshing() } 
5
19 июля '14 в 9:26 2014-07-19 09:26 Cavab 19 yaşındakı Renish Dadhaniya tərəfindən verilir , '14 'da 9:26 2014-07-19 09:26

performSelector() istifadə edərkən

/addtarget()/NStimer.scheduledTimerWithInterval() metodunuz ( /addtarget()/NStimer.scheduledTimerWithInterval() müvafiq olaraq)

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

Swift 2.2 üçün simli ad və selector əvəzinə '#selector ()' yazmalısınız, beləliklə yazım səhvləri və bu səbəbdən uğursuzluq mümkün olmayacaqdır. Aşağıda bir nümunədir.

 self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5) 
4
17 марта '16 в 9:48 2016-03-17 09:48 cschunara cavab 17 mart '16 saat 9:48 2016-03-17 09:48 verilir

Aşağıda göstərildiyi kimi bir selektor yaratmaq.
1.

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

2

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

@Selector sözdiziminin eksik olduğuna və zəng üsulunu çağıraraq sadə bir simli ilə əvəz olunduğuna diqqət yetirin. Yol boyunca alınan detallar barədə hamımızın razı olacağı bir sahə var. Əlbəttə ki, flatButtonPressed adlı bir hədəf metodunun olduğunu elan edərdik: bir yazmaq daha yaxşıdır:

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

Taymeri təyin et:

  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 

Tam olmaq üçün, heres flatButtonPressed

 func flatButtonPressed(timer: NSTimer) { } 
3
11 июля '14 в 22:14 2014-07-11 22:14 Cavab Daxesh Nagar tərəfindən 11 iyul 11:14 'də verilir. 2014-07-11 22:14

#Selector istifadə edərək, çağırmaq istədiyiniz metodu həqiqətən mövcud olduğundan əmin olmaq üçün kompilyasiya vaxtında kodunuzu yoxlayır. Daha da yaxşıdır ki, əgər metod mövcud deyilsə, kompilyasiya səhviniz olacaq: Xcode tətbiqinizi qurmaqdan imtina edəcək və bununla yanaşı digər mümkün səhvlərin mənbəyini unutma.

 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!") } 
3
20 мая '16 в 14:31 2016-05-20 14:31 Cavab Swift Developer tərəfindən 20 May '14 ' də 14:31 2016-05-20 14:31' də verilir

Mən bu cavabların bir çoxunun faydalı olduğunu anladım, ancaq bir düyməyə bənzəməyən bir şey ilə bunu necə etmək lazım olduğu aydın deyil. UILabel'deki jest tanıyanını tez bir zamanda əlavə etdim və topladığım hər şeyi oxuduqdan sonra mənim üçün çalışdığım üçün mübarizə etdi:

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

"Selector" elan edildikdə:

 func labelTapped(sender: UILabel) { } 

Qeyd edək ki, bu ictimaiyyətdir və Selector () sözdizimini istifadə etmirəm, amma bunu etmək mümkündür.

 let tapRecognizer = UITapGestureRecognizer( target: self, action: Selector("labelTapped:")) 
3
14 февр. cynistersix tərəfindən verilmiş cavab 14 fevral. 2016-02-14 20:58 '16 saat 20:58 'da 2016-02-14 20:58

Hərəkəti tetikleyen kontrolü quraşdırdığınız yeri qeyd etmək faydalı ola bilər.

Məsələn, mən gördüm ki, UIBarButtonItem qurarkən viewDidLoad içərisində bir düyməni yaratmaq üçün lazım idi, əks halda seçilməmiş seçici istisnası alacaqdım.

 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") } 
2
12 июля '14 в 22:33 2014-07-12 22:33 Cavab Michael Peterson tərəfindən 12 İyul, '14 'saat 22:33 ' də verilir 2014-07-12 22:33

Sütun sözdizimini çağırdıran bir üsulla sadə simli adlandırma kimi dəyişdirin

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

Bundan sonra func testini () daxil edin.

1
14 окт. Cavab Thar Htet 14 oktyabr tərəfindən verilir . 2014-10-14 07:49 '14 da 7:49 2014-10-14 07:49

Swift 4 seçicisi:

 button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside) 
0
19 нояб. Mahesh Chaudhari tərəfindən verilmiş cavab 19 noyabr 2018-11-19 13:26 '18 saat 13:26 'da 2018-11-19 13:26

Tez 3

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

Eyni sinifdə fəaliyyət bəyannaməsi

 func test() { // my function } 
0
28 февр. Cavab Mustajab Cafri tərəfindən verilir 28 fevral. 2017-02-28 09:41 '17 saat 09:41 2017-02-28 09:41

Swift üçün 3

// bir timer yaratmaq üçün nümunə kodu

 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. 
0
19 мая '18 в 20:03 2018-05-19 20:03 Cavab CrazyPro007 tərəfindən verilir 19 May '18 saat 20:03 2018-05-19 20:03

haqqında digər suallar və ya bir sual