कक्षा Y का ऑब्जेक्ट X स्विफ्ट में मेथड्स सिग्नचरफॉर सेलेक्टर को लागू नहीं करता है


89

मेरे पास एक क्लास पर्सन है, जो कई बार इंस्टेंट हो जाता है। हर व्यक्ति को अपना टाइमर मिल जाता है। मेरे initलिए Personमेरे फोन पर startTimer()

class Person {
 var timer = NSTimer()
 func startTimer() {
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("timerTick"), userInfo: nil, repeats: true)
 }

 func timerTick() {
    angerLevel++
    println("Angry! \(angerLevel)")
 }
...
...
}

तो मेरे पास एक सरणी में व्यक्ति के 3 उदाहरण हो सकते हैं Person[]। मुझे एक त्रुटि मिल रही है:

2014-06-25 13:57:14.956 ThisProgram[3842:148856] *** NSForwarding: warning: object 0x113760048 of class '_TtC11ThisProgram6Person' does not implement methodSignatureForSelector: -- trouble ahead

मैं कहीं और पढ़ता हूं कि मुझे इनहेरिट करना चाहिए NSObjectलेकिन यह स्विफ्ट में नहीं ओज-सी में है। फ़ंक्शन कक्षा के भीतर है इसलिए मुझे यकीन नहीं है कि क्या करना है।


4
आप पहले ही समझ गए थे कि वर्ग को NSObject से विरासत में मिलना चाहिए class Person : NSObject { ... }:। क्या आप एक अलग समाधान की तलाश कर रहे हैं?
मार्टिन आर

जवाबों:


160

NSObjectएक उद्देश्य-सी वर्ग के रूप में मत सोचो, इसे कोको / फाउंडेशन वर्ग के रूप में सोचो। भले ही आप उद्देश्य-सी के बजाय स्विफ्ट का उपयोग कर रहे हों, फिर भी आप सभी समान रूपरेखाओं का उपयोग कर रहे हैं।

दो विकल्प: (1) dynamicउस फ़ंक्शन को विशेषता जोड़ें जिसे आप एक चयनकर्ता के रूप में संदर्भित करना चाहते हैं:

    dynamic func timerTick() {
        self.angerLevel++
        print("Angry! \(self.angerLevel)")
    }

या (2) के Personउपवर्ग के रूप में घोषित NSObjectकरें, फिर super.init()अपने आरंभक की शुरुआत में कॉल करें :

class Person: NSObject {
    var timer = NSTimer()
    var angerLevel = 0

    func startTimer() {
        print("starting timer")
        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "timerTick", userInfo: nil, repeats: true)
    }

    func timerTick() {
        self.angerLevel++
        print("Angry! \(self.angerLevel)")
    }

    override init() {
        super.init()
        self.startTimer()
    }
}

3
आपको इस तरह से फ़ंक्शन घोषणा को सजाने में सक्षम होना चाहिए @objc func timerTick()। NSTimer एपीआई Obj-C रनटाइम पर काफी निर्भर करता है।
मक्षोम

अच्छा कॉल - जवाब में जोड़ा गया
नैट कुक

1
इस मुद्दे को धन्यवाद मेरी समस्या। लेकिन क्या आप समझा सकते हैं कि क्यों? @Objc भाग को इसकी क्या आवश्यकता है?
अग्रदूत

NSTimerलक्षित चयनकर्ता को कॉल करने के लिए संदेश अग्रेषण का उपयोग करता है, जो कि डिफ़ॉल्ट रूप से स्विफ्ट प्रकारों पर नियंत्रित नहीं की गई एक उद्देश्य-सी सुविधा है। जब आप @objcविशेषता का उपयोग करते हैं या एक उद्देश्य-सी श्रेणी से प्राप्त करते हैं, तो आप कई सुविधाओं में चयन कर रहे हैं, जिसमें संदेश अग्रेषण शामिल है।
नैट कुक

2
इनमें से किसी भी समाधान की अब आवश्यकता नहीं है। यह चयनकर्ता समारोह घोषित करने के लिए पर्याप्त है dynamic। वे दोनों अच्छे हैं और वे दोनों अभी भी काम करते हैं, लेकिन dynamicइस एक फ़ंक्शन का उपयोग करके अधिक हल्का दृष्टिकोण देखा जा सकता है।
मैट

32

XCode6 बीटा 6 के बाद से, आप 'डायनामिक' फंक का उपयोग कर सकते हैं

dynamic func timerTick() { .... }

यह मेरी समस्या को हल करने की कोशिश कर रहा है UILocalizedIndexedCollation.currentCollation () का उपयोग करने की कोशिश कर रहा
डॉगी

यह NSObject से संपूर्ण वर्ग को वंशानुगत बनाने का एक बेहतर तरीका है।
बॉब

8

मेरे पास एक समान त्रुटि का उपयोग करने की कोशिश कर रहा था let encodedArchive = NSKeyedArchiver.archivedDataWithRootObject(archive) as NSDataजहां संग्रह एक कस्टम वर्ग की एक सरणी थी। मैंने पाया कि उस कस्टम क्लास को NSObject और NSCoding के उपवर्ग के रूप में घोषित करने ने चाल चली। इसे NSCoding के प्रोटोकॉल के अनुरूप करने के लिए कुछ और लाइनों की आवश्यकता होगी ताकि यह कुछ इस तरह से शुरू हो जाए:

class Person: NSObject, NSCoding {
  init() {
    super.init()
  }

  func encodeWithCoder(_aCoder: NSCoder) {   }
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.