@ स्विफ्टर () स्विफ्ट में?


659

मैं एक बनाने की कोशिश कर रहा हूँ NSTimer, Swiftलेकिन मुझे कुछ परेशानी हो रही है।

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

test() एक ही कक्षा में एक समारोह है।


मुझे संपादक में त्रुटि मिलती है:

आपूर्ति किए गए तर्कों को स्वीकार करने वाले 'init' के लिए अधिभार नहीं मिला

जब मैं त्रुटि में परिवर्तित हो selector: test()जाता है selector: nilतो गायब हो जाता है।

मैंने कोशिश की:

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

लेकिन कुछ भी नहीं काम करता है और मैं संदर्भ में एक समाधान नहीं मिल सकता है।


11
selector: test()कॉल testऔर पास होगा यह selectorतर्क के लिए वापसी मूल्य है ।
माइकल डोरस्ट

जवाबों:


930

स्विफ्ट स्वयं चयनकर्ताओं का उपयोग नहीं करता है - कई डिज़ाइन पैटर्न जो ऑब्जेक्ट-सी में चयनकर्ताओं का उपयोग स्विफ्ट में अलग तरीके से काम करते हैं। (उदाहरण के लिए, प्रोटोकॉल प्रकारों या is/ asपरीक्षणों के बजाय वैकल्पिक चाइनिंग respondsToSelector:का उपयोग करें, और जहाँ भी आप performSelector:बेहतर / स्मार्ट मेमोरी सुरक्षा के लिए उपयोग कर सकते हैं, वहां क्लोजर का उपयोग करें ।)

लेकिन अभी भी कई महत्वपूर्ण ObjC- आधारित API हैं जो चयनकर्ताओं का उपयोग करते हैं, जिनमें टाइमर और लक्ष्य / एक्शन पैटर्न शामिल हैं। स्विफ्ट Selectorइन के साथ काम करने के लिए प्रकार प्रदान करता है । (स्विफ्ट अपने आप इसे ओबीजीसी के SELप्रकार के स्थान पर उपयोग करता है ।)

स्विफ्ट 2.2 (एक्सकोड 7.3) और बाद में (स्विफ्ट 3 / एक्सकोड 8 और स्विफ्ट 4 / एक्सकोड 9 सहित):

आप अभिव्यक्ति Selectorका उपयोग करके एक स्विफ्ट फ़ंक्शन प्रकार से निर्माण कर सकते हैं #selector

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)

इस दृष्टिकोण के बारे में महान बात? एक फ़ंक्शन संदर्भ स्विफ्ट कंपाइलर द्वारा जांचा जाता है, इसलिए आप #selectorकेवल क्लास / मेथोड जोड़े के साथ अभिव्यक्ति का उपयोग कर सकते हैं जो वास्तव में मौजूद हैं और चयनकर्ताओं के रूप में उपयोग के लिए योग्य हैं (नीचे "चयनकर्ता उपलब्धता देखें")। आप फ़ंक्शन-टाइपिंग नामकरण के लिए स्विफ्ट 2.2+ नियमों के अनुसार, अपने फ़ंक्शन को केवल आवश्यकतानुसार विशिष्ट बनाने के लिए स्वतंत्र हैं ।

(यह वास्तव में ObjC के @selector()निर्देश पर एक सुधार है , क्योंकि संकलक की -Wundeclared-selectorजांच केवल यह बताती है कि नामित चयनकर्ता मौजूद है। स्विफ्ट फ़ंक्शन संदर्भ आप #selectorअस्तित्व की जांच करने के लिए पास करते हैं, एक वर्ग में सदस्यता, और हस्ताक्षर टाइप करते हैं।)

#selectorअभिव्यक्ति के लिए जाने वाले फ़ंक्शन संदर्भों के लिए कुछ अतिरिक्त चेतावनी हैं :

  • एक ही आधार नाम के साथ कई फ़ंक्शन फ़ंक्शन संदर्भ (उदाहरण insertSubview(_:at:)बनाम insertSubview(_:aboveSubview:)) के लिए उपरोक्त सिंटैक्स का उपयोग करके उनके पैरामीटर लेबल द्वारा विभेदित किए जा सकते हैं । लेकिन अगर किसी फ़ंक्शन का कोई पैरामीटर नहीं है, asतो फ़ंक्शन के प्रकार हस्ताक्षर (जैसे foo as () -> ()बनाम foo(_:)) के साथ कलाकारों का उपयोग करने का एकमात्र तरीका है ।
  • स्विफ्ट 3.0+ में संपत्ति पाने वाले / सेटर जोड़े के लिए एक विशेष वाक्यविन्यास है। उदाहरण के लिए, दिए गए var foo: Int, आप उपयोग कर सकते हैं #selector(getter: MyClass.foo)या #selector(setter: MyClass.foo)

सामान्य टिप्पणी:

ऐसे मामले जहां #selectorकाम नहीं करता है, और नामकरण: कभी-कभी आपके पास चयनकर्ता बनाने के लिए एक फ़ंक्शन संदर्भ नहीं होता है (उदाहरण के लिए, ओबजैक रनटाइम में गतिशील रूप से पंजीकृत तरीकों के साथ)। उस स्थिति में, आप Selectorएक स्ट्रिंग से निर्माण कर सकते हैं : जैसे Selector("dynamicMethod:")- यद्यपि आप संकलक की वैधता जाँच खो देते हैं। जब आप ऐसा करते हैं, तो आपको :प्रत्येक पैरामीटर के लिए colons ( ) सहित ObjC नामकरण नियमों का पालन करने की आवश्यकता होती है ।

चयनकर्ता की उपलब्धता: चयनकर्ता द्वारा संदर्भित विधि को ओबीजीसी रनटाइम से अवगत कराया जाना चाहिए। स्विफ्ट 4 में, ObjC के सामने आने वाली हर विधि की @objcविशेषता के साथ इसकी घोषणा पूर्व निर्धारित होनी चाहिए । (पिछले संस्करणों में आपको कुछ मामलों में वह विशेषता मुफ्त में मिली थी, लेकिन अब आपको इसे स्पष्ट रूप से घोषित करना होगा।)

उसे याद रखो private प्रतीकों को रनटाइम के संपर्क में नहीं किया जाता है, भी - आपकी विधि को कम से कम internalदृश्यता की आवश्यकता है।

मुख्य पथ: ये संबंधित हैं, लेकिन चयनकर्ताओं के समान नहीं हैं। स्विफ्ट 3 में इनके लिए एक विशेष वाक्यविन्यास है, जैसे: उदा chris.valueForKeyPath(#keyPath(Person.friends.firstName))। देखें एसई 0062 जानकारी के लिए। और भी अधिकKeyPath स्विफ्ट 4 में सामान , इसलिए सुनिश्चित करें कि आप उचित KeyPath- आधारित एपीआई का उपयोग कर रहे हैं यदि चयनकर्ताओं के बजाय उचित हो।

आप के तहत चयनकर्ताओं के बारे में अधिक पढ़ सकते हैं ऑब्जेक्टिव-सी एपीआई के साथ बातचीत में कोको और ऑब्जेक्टिव-सी के साथ स्विफ्ट का उपयोग करना

नोट: स्विफ्ट 2.2 से पहले, के Selectorअनुरूप है StringLiteralConvertible, इसलिए आपको पुराना कोड मिल सकता है जहां चयन करने वाले एपीआई को नंगे तार दिए जाते हैं। आप का उपयोग करने के लिए Xcode में "कन्वर्ट करने के लिए वर्तमान स्विफ्ट सिंटैक्स" चलाना चाहते हैं #selector


8
कार्य नाम के साथ एक स्ट्रिंग डालकर काम किया, NSSelectorFromString () भी काम करता है।
आर्बिटुर

7
मैं यह उल्लेख करना चाहता हूं कि वेबसाइट पर "ऑब्जेक्टिव-सी एपीआई के साथ बातचीत" करते समय, यह 'द स्विफ्ट प्रोग्रामिंग लैंग्वेज' पुस्तक में नहीं है।

10
यह शायद उल्लेख करना चाहिए कि चयनकर्ता को एक तर्क में ":" की आवश्यकता है। (उदाहरण के लिए परीक्षण () -> "परीक्षण" और परीक्षण (यह: स्ट्रिंग) -> "परीक्षण:")
डैनियल Schlaug

2
यह भी ध्यान दिया जाना चाहिए कि कोको फ्रेमवर्क एक उद्देश्य-सी शैली विधि नाम की उम्मीद करता है। अपने विधि एक तर्क लेता है, तो आप एक की आवश्यकता होगी ':' अगर यह 2 तर्क लेता है, size:andShape:अगर पहले तर्क के नाम पर है आप एक आवश्यकता हो सकती है With, यानी initWithData:के लिएfunc init(Data data: NSData)
JMFR

6
वैसे भी "चयनकर्ता" को एक स्ट्रिंग के रूप में पारित करने के लिए सत्यापन जोड़ने के लिए क्या है? IE कम्पाइलर हमें चेतावनी देता है जब हम गलत करते हैं, आदि
yo.ian.g

86

Selectorस्विफ्ट पर क्लास का उपयोग कैसे करें, इस पर एक त्वरित उदाहरण है :

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   
}

ध्यान दें कि यदि स्ट्रिंग के रूप में दिया गया तरीका काम नहीं करता है, तो यह रनटाइम में विफल हो जाएगा, समय संकलन नहीं, और आपके ऐप को क्रैश कर देगा। सावधान रहे


13
जो भयानक है ... वहाँ एक "NSStringFromSelector" बात है?
लीना ब्रू

11
विश्वास नहीं कर सकता कि वे अनियंत्रित चयनकर्ताओं के लिए डिज़ाइन किए गए थे क्योंकि objc के पास यह था
malhal

4
@malcomhall: @selectorकाम है, लेकिन यह औपचारिक रूप से लागू नहीं है जैसा कि आप सोच सकते हैं। "अघोषित चयनकर्ता" केवल संकलक से एक चेतावनी है, क्योंकि नए चयनकर्ताओं को हमेशा रन टाइम पर पेश किया जा सकता है। हालांकि स्विफ्ट में सत्यापन योग्य / रिफैक्टेबल चयनकर्ता एक अच्छा फीचर अनुरोध होगा , हालांकि।
22

2
यह उत्तर सहायक है लेकिन @objc के साथ नीचे का उत्तर अधिक उपयुक्त है।
cynistersix

जब आप चयनकर्ता स्ट्रिंग को एक चर या पैरामीटर के रूप में पारित कर रहे हैं, तो आपको चयनकर्ता को चयनकर्ता () फ़ंक्शन का उपयोग करने की जानकारी देने की आवश्यकता होगी। धन्यवाद
levous

46

इसके अलावा, यदि आपकी (स्विफ्ट) क्लास ऑब्जेक्टिव-सी क्लास से नहीं उतरती है, तो आपके पास टारगेट मेथड नेम स्ट्रिंग के अंत में एक कोलोन होना चाहिए और आपको अपने टारगेट मेथड के साथ @objc प्रॉपर्टी का इस्तेमाल करना होगा।

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

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

अन्यथा आपको रनटाइम के दौरान "गैर मान्यता प्राप्त चयनकर्ता" त्रुटि मिलेगी।


3
1. चयनकर्ताओं w / एक बृहदान्त्र को एक तर्क लेना चाहिए। Apple डॉक्स के अनुसार टाइमर की कार्रवाइयों में NSTimer तर्क लेना चाहिए। Selectorकीवर्ड अनिवार्य नहीं है। तो इस मामले में हस्ताक्षर होना चाहिए@objc func method(timer: NSTimer) {/*code*/}
येवैन दुबीनिन

@objcमेरे लिए काम किया। मुझे timer: NSTimerअपने विधि हस्ताक्षर में इसे शामिल करने की आवश्यकता नहीं थी ।
माइक टैवर्न

32

स्विफ्ट 2.2+ और स्विफ्ट 3 अपडेट

नई #selectorअभिव्यक्ति का उपयोग करें , जो कम त्रुटि वाले उपयोग स्ट्रिंग स्ट्रिंग को उपयोग करने की आवश्यकता को समाप्त करता है। सन्दर्भ के लिए:

Selector("keyboardDidHide:")

हो जाता है

#selector(keyboardDidHide(_:))

इसे भी देखें: स्विफ्ट इवोल्यूशन प्रपोजल

नोट (स्विफ्ट 4.0):

यदि उपयोग कर रहे हैं #selector कर के रूप में समारोह को चिह्नित करने की आवश्यकता होगी@objc

उदाहरण:

@objc func something(_ sender: UIButton)


26

स्विफ्ट 4.0

आप नीचे की तरह चयनकर्ता बनाएँ।

1. घटना को एक बटन की तरह देखें:

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

और समारोह नीचे की तरह होगा:

@objc func clickedButton(sender: AnyObject) {

}

4
आप स्विफ्ट 4 में जो @objcपहले funcआवश्यक है, उसे भूल गए ।
वाहिद अमीरी

24

भविष्य के पाठकों के लिए, मैंने पाया कि मुझे एक समस्या का सामना करना पड़ा और एक unrecognised selector sent to instanceत्रुटि मिल रही थी जो लक्ष्य को चिह्नित करने के कारण हुई थीfunc को निजी के रूप में ।

func चाहिए सार्वजनिक रूप से एक चयनकर्ता के लिए एक संदर्भ के साथ एक वस्तु से कहा जा को दिखाई।


13
इसे सार्वजनिक करने की आवश्यकता नहीं है आप अभी भी विधि को निजी रख सकते हैं लेकिन objcघोषणा से पहले इसे जोड़ सकते हैं । Ex: @objc private func foo() { ...तब आप "foo"एक चयनकर्ता के रूप में उपयोग कर सकते हैं जितना आप चाहते हैं
apouche

यह भी हो सकता है internal, इस प्रकार किसी भी पहुँच संशोधक को निर्दिष्ट नहीं किया जा सकता है । मैं अक्सर इस पैटर्न का उपयोग करता हूं://MARK: - Selector Methods\n extension MyController {\n func buttonPressed(_ button: UIButton) {
सज्जन

19

बस अगर किसी और की समस्या वही है जो मैंने NSTimer के साथ की है, जहाँ किसी भी अन्य ने इस मुद्दे को तय नहीं किया है, तो यह उल्लेख करना वास्तव में महत्वपूर्ण है कि, यदि आप एक वर्ग का उपयोग कर रहे हैं जो NSObject से विरासत में सीधे या गहरे में नहीं मिलता है ( उदाहरण के लिए मैन्युअल रूप से बनाई गई स्विफ्ट फाइलें), निम्न में से निर्दिष्ट होने पर भी कोई भी अन्य उत्तर काम नहीं करेगा:

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

NSObject से सिर्फ क्लास को इनहेरिट करने के अलावा कुछ और बदलने के बिना मैंने "Unrecognized selector" एरर मिलना बंद कर दिया और अपने लॉजिक को उम्मीद के मुताबिक काम करने लगा।


इस विकल्प के साथ मुद्दा यह है कि आप NSObject से इनहेरिट करने के लिए एक वर्ग को बदल सकते हैं (LetController कह सकते हैं), यह देखते हुए कि आपको ViewController वर्ग कार्यान्वित सामान (जैसे viewDidLoad ()) की आवश्यकता है। किसी भी विचार कैसे NSTimer का उपयोग करके एक ViewController के भीतर एक स्विफ्ट फ़ंक्शन को कॉल करने के लिए? ... e
eharo2

1
UIViewController पहले से ही NSObject से विरासत में मिली है, ज्यादातर कक्षाएं SDK द्वारा उजागर की जाती हैं, यह उदाहरण आपके स्वयं के बनाए गए वर्गों के लिए है जिन्हें NSTimer कार्यक्षमता की आवश्यकता होती है ...
मार्टिन काज़रेस

14

यदि आप 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)
}

चयनकर्ता पाठ (टेस्टर :) में कोलन को शामिल करें, और आपका पैरामीटर userInfo में जाएं।

आपके फ़ंक्शन को पैरामीटर के रूप में NSTimer लेना चाहिए। तो बस पारित करने के लिए पैरामीटर प्राप्त करने के लिए userInfo निकालें।


3
मैं NSTimer (0.01, लक्ष्य: स्वयं, ...) का उपयोग कर रहा था, जिसने काम नहीं किया, जबकि NSTimer.scheduledTimerWithTimeInterval (0.01, ..) का उपयोग करते हुए काम किया !? अजीब लेकिन धन्यवाद @Scooter आप जवाब के लिए!
iOS-Coder

1
@ आईओएस-कोडर बस इनिशियलाइज़र के साथ एक टाइमर बनाने के लिए इसे एक रन-अप में नहीं scheduledTimerWith...जोड़ता है , जबकि स्वचालित रूप से इसे वर्तमान रन-अप में जोड़ता है - इसलिए यहाँ कोई अजीब व्यवहार नहीं है;)
डेविड गैंस्टर

1
@ अपने सुझाव के लिए धन्यवाद। मुझे लगता है कि मेरी गलतफहमी STFW या RTFA (पढ़ें एफ ... आईएनजी एपीआई) श्रेणी में होनी चाहिए?
iOS-Coder

1
इसके बारे में चिंता न करें, किसी से यह उम्मीद नहीं की जा सकती कि वह हर एपीआई में हर एक विधि के बारे में दस्तावेज पढ़े;)
डेविड गैंस्टर

10

चयनकर्ता ऑब्जेक्टिव-सी में एक विधि नाम का आंतरिक प्रतिनिधित्व हैं। ऑब्जेक्टिव-सी में "@selector (methodName)" एक सोर्स-कोड विधि को डेटा प्रकार के SEL में बदल देगा। चूँकि आप Swift (rickster वहाँ बिंदु पर) में @selector सिंटैक्स का उपयोग नहीं कर सकते हैं, आपको मैन्युअल रूप से स्ट्रींग ऑब्जेक्ट के रूप में विधि का नाम निर्दिष्ट करना होगा, या चयनकर्ता प्रकार के लिए स्ट्रिंग ऑब्जेक्ट पास करके। यहाँ एक उदाहरण है:

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

या

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

8

स्विफ्ट 4.1
टैप जेस्चर के नमूने के साथ

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

के बारे में अधिक जानकारी के लिए Apple के दस्तावेज़ देखें: चयनकर्ता अभिव्यक्ति


कृपया ऐसा करना बंद करें। यह मदद करता है कोई नहीं। यह स्विफ्ट 3.1 से कैसे अलग है? और आपने इसके बारे में एक और उत्तर जोड़ना क्यों जरूरी समझा जब इसके पहले से ही लगभग 20 उत्तर हैं?
फोगमिस्टर

कॉलिंग सेलेक्टर स्विफ्ट में अलग है। स्विफ्ट 4 में इन उत्तरों को आज़माएं और देखें। बिना संपादन के ये कोई भी काम नहीं करेंगे। कृपया अपने impotance सुनिश्चित बिना स्पैम के रूप में किसी भी बयान में चिह्नित न करें
Krunal

तो क्या कोई कारण है कि आप मौजूदा, स्वीकृत उत्तर को संपादित नहीं कर सकते हैं? यह उत्तरों की लंबी सूची के अंत में जोड़ने के बजाय इसे वास्तव में उपयोगी बना देगा। "एडिट" बटन एक कारण से है।
फोगमिस्टर

इसके अलावा, स्विफ्ट 3 से इसका कौन सा हिस्सा अलग है?
फोगमिस्टर

2
आपको Swift 4 के लिए किसी भी चयनकर्ता के पास objc टैग जोड़ना होगा। यह सही उत्तर है। और अपने अर्थ को बदलने के लिए अन्य लोगों के उत्तरों को संपादित नहीं करना चाहिए। @ क्रुणाल पूरी तरह से सही हैं।
अनोम

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
}

यह अच्छा और अधिक शिक्षाप्रद होता यदि यू के पास स्विफ्ट 3 या स्विफ्ट 4 के लिए भी दो या तीन तर्क देने वाला उदाहरण होता। धन्यवाद।
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)

// ताज़ा नियंत्रण विधि

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

}

5

चूंकि स्विफ्ट 3.0 प्रकाशित है, इसलिए लक्ष्य को उपयुक्त घोषित करना थोड़ा अधिक सूक्ष्म है

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

4

उपयोग करते समय performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval() आपके तरीके (चयनकर्ता से मेल खाते) को इस रूप में चिह्नित किया जाना चाहिए

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

स्विफ्ट 2.2 के लिए, आपको स्ट्रिंग और चयनकर्ता के नाम के बजाय '#selector ()' लिखना होगा ताकि वर्तनी की त्रुटि और उसके कारण दुर्घटना की संभावना अब नहीं होगी। नीचे उदाहरण है

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

3

आप नीचे दिए गए चयनकर्ता को बनाएं।
1।

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

2।

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

ध्यान दें कि @selector सिंटैक्स चला गया है और कॉल करने के लिए एक सरल स्ट्रिंग नामकरण के साथ बदल दिया गया है। एक ऐसा क्षेत्र है जहां हम सभी सहमत हो सकते हैं कि जिस तरह से क्रियाशीलता मिली है। बेशक, अगर हमने घोषणा की कि फ्लैटबटन नामक एक लक्ष्य विधि है: हम बेहतर लिखते हैं:

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

टाइमर सेट करें:

    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

पूरा होने के क्रम में, यहाँ फ्लैटबटनप्रेस्ड है

func flatButtonPressed(timer: NSTimer) {
}

क्या आपके पास " नोट नोट करें कि @selector सिंटैक्स चला गया है " के लिए कोई स्रोत है ?
विंकलेरर

3

मुझे इनमें से कई उत्तर मददगार लगे लेकिन यह स्पष्ट नहीं था कि ऐसा कैसे किया जाए जो बटन नहीं था। मैं स्विफ्ट में एक यूबेलबेल के लिए एक इशारा पहचानकर्ता को जोड़ रहा था और संघर्ष कर रहा था, इसलिए यहाँ पाया गया कि मैंने सब कुछ करने के बाद मेरे लिए काम किया:

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

जहां "चयनकर्ता" के रूप में घोषित किया गया था:

func labelTapped(sender: UILabel) { }

ध्यान दें कि यह सार्वजनिक है और मैं चयनकर्ता () सिंटैक्स का उपयोग नहीं कर रहा हूं, लेकिन ऐसा करना संभव है।

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

3

#Selector का उपयोग करके आपके कोड को संकलन के समय पर जांच लिया जाएगा कि यह सुनिश्चित करने के लिए कि जिस विधि को आप कॉल करना चाहते हैं वह वास्तव में मौजूद है। इससे भी बेहतर, अगर विधि मौजूद नहीं है, तो आपको एक संकलन त्रुटि मिलेगी: Xcode आपके ऐप को बनाने से इनकार कर देगा, इस प्रकार कीड़े के एक अन्य संभावित स्रोत को विस्मरण कर देगा।

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

2

यह नोट करना उपयोगी हो सकता है कि आप उन मामलों को नियंत्रित करते हैं जो कार्रवाई के मामलों को ट्रिगर करते हैं।

उदाहरण के लिए, मैंने पाया है कि UIBarButtonItem की स्थापना करते समय, मुझे viewDidLoad के भीतर बटन बनाना था या फिर मुझे एक अज्ञात चयनकर्ता अपवाद मिलेगा।

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

1

चयनकर्ता सिंटैक्स के लिए कॉल करने की विधि में एक सरल स्ट्रिंग नामकरण के रूप में बदलें

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

उसके बाद, फंक टेस्ट () टाइप करें।


1

selectorObjective-Cदुनिया का एक शब्द है और आप इसे Swiftकॉल करने की संभावना से उपयोग करने में सक्षम हैं Objective-CSwift यह आपको रनटाइम पर कुछ कोड निष्पादित करने की अनुमति देता है

Swift 2.2वाक्य रचना से पहले है:

Selector("foo:")

चूंकि एक फ़ंक्शन नाम को Selectorस्ट्रिंग पैरामीटर ("फू") के रूप में पास किया गया है , इसलिए संकलन समय में नाम की जांच करना संभव नहीं है । परिणामस्वरूप आप रनटाइम त्रुटि प्राप्त कर सकते हैं:

unrecognized selector sent to instance

Swift 2.2+वाक्य रचना के बाद है:

#selector(foo(_:))

Xcode की स्वतः पूर्णता आपको एक सही विधि बताने में मदद करती है


0

स्विफ्ट 3 के लिए

// टाइमर बनाने के लिए नमूना कोड

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.


-1

स्विफ्ट 3 के लिए

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

समारोह की घोषणा उसी वर्ग में:

@objc func test()
{
    // my function
} 

यदि लक्ष्य स्वयं है, तो selfचयनकर्ता में होने की आवश्यकता नहीं है । यह पर्याप्त होना चाहिए:let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(test), userInfo: nil, repeats: true)
मिश्रा सिंघम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.