swift - vxi - कंपाइलर त्रुटि: ऑब्जेक्टिव-सी चयनकर्ता के साथ विधि एक ही ऑब्जेक्टिव-सी चयनकर्ता के साथ पिछले घोषणा के साथ संघर्ष करती है




swift vxi (4)

मैं स्विफ्ट सीखना शुरू कर रहा हूं, और YouTube पर बहुत अच्छे स्टैनफोर्ड यूनिवर्सिटी वीडियो व्याख्यान का पालन कर रहा हूं। यहाँ एक लिंक है यदि आप रुचि रखते हैं या यह मदद करता है (हालांकि यह मेरी समस्या को समझने के लिए आवश्यक नहीं है):

स्विफ्ट के साथ आईओएस 8 ऐप विकसित करना - 2. अधिक एक्सकोड और स्विफ्ट, एमवीसी

व्याख्यान के बाद मुझे एक बिंदु मिला जहां (जहां तक ​​मैं बता सकता था) मेरा कोड वीडियो में कोड के समान था लेकिन मेरे सिस्टम पर मुझे एक संकलक त्रुटि मिली। बहुत सारे परीक्षण और त्रुटि के बाद मैंने अपने कोड को दो उदाहरणों में कम करने में कामयाब रहा है, जिनमें से एक त्रुटि उत्पन्न करता है, दूसरा या जो नहीं करता है, लेकिन मुझे नहीं पता कि वास्तव में त्रुटि का कारण क्या है या इसे कैसे हल किया जाए।

त्रुटि पैदा करने वाला कोड है:

import UIKit

class BugViewController: UIViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

यह निम्नलिखित संकलक त्रुटि बनाता है:

उद्देश्य-सी चयनकर्ता के साथ विधि 'प्रदर्शन' प्रदर्शन: 'एक ही उद्देश्य-सी चयनकर्ता के साथ पिछले घोषणा के साथ संघर्ष

बस कोड संकलन UIViewController के उप-क्लासिंग को हटाकर:

import UIKit

class BugViewController
{
    func perform(operation: (Double) -> Double) {
    }

    func perform(operation: (Double, Double) -> Double) {
    }
}

कुछ अन्य जानकारी जो प्रासंगिक हो सकती है या नहीं भी हो सकती है:

  • मैंने हाल ही में योसेमाइट में अपग्रेड किया है।
  • जब मैंने Xcode स्थापित किया, तो मैं एक बीटा संस्करण (संस्करण 6.3 (6D543q)) के साथ समाप्त हो गया क्योंकि (यदि मुझे सही याद है) तो यह वह संस्करण था जिसे मुझे ओएस एक्स के मेरे संस्करण पर चलाने की आवश्यकता थी।

मैं उम्मीद कर रहा हूं कि यह कंपाइलर में एक बग है क्योंकि अन्यथा इससे मुझे कोई मतलब नहीं है। कोई मदद बहुत आभार प्राप्त!


"Xcode 6.3 रिलीज़ नोट्स" के तहत https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html से - "स्विफ्ट लैंग्वेज चेंजेज़" - आप पाते हैं

स्विफ्ट अब स्विफ्ट प्रकार प्रणाली में ओवरलोडिंग और ओवरराइडिंग और ऑब्जेक्टिव-सी रनटाइम के माध्यम से देखे जाने वाले प्रभावी व्यवहार के बीच विसंगतियों का पता लगाता है।


एक ही Obj-C हस्ताक्षर के साथ दो विधियाँ होने के कारण मुझे वही त्रुटि मिली:

static func prepareForUpSyncing(obj : NSManagedObject!) -> Bool
static func prepareForUpSyncing(objs : [NSManagedObject]!) -> Bool

मैं रनटाइम पर अप्रत्याशित परिणामों की संभावना के कारण उनमें से एक @nonobjc के रूप में चिह्नित नहीं करना चाहता था। (अगर कोई संभावना नहीं है तो कोई मुझे सही कर सकता है)

स्विफ्ट के बाहरी पैरामीटर नाम सुविधा (मैंने स्थानीय नाम के समान बाहरी नाम) को दूसरी विधि का उपयोग करके इसे हल किया, जो प्रभावी रूप से ओबज-सी विधि हस्ताक्षर को बदलता है:

static func prepareForUpSyncing(objs objs : [NSManagedObject]!) -> Bool {

जैसा कि यह पहले ही उत्तर दिया जा चुका है, ओबजैक विधि ओवरलोडिंग (एक ही नाम के दो तरीके) का समर्थन नहीं करता है और Xcode 7 के तहत स्विफ्ट 2 में इस तरह की समस्याओं को हल करने के लिए दो विकल्प हैं। एक विकल्प विशेषता का उपयोग करके विधि का नाम बदलना है: @objc(newNameMethod:)

func methodOne(par1, par2) {...}

@objc(methodTwo:)
func methodOne(par1) {...}

Xcode 7+ में इस समस्या को हल करने का एक अन्य विकल्प @nonobjc विशेषता को किसी भी विधि, सबस्क्रिप्ट या @nonobjc लागू करना है

func methodOne() {...}

@nonobjc
func methodOne() {...}

मैं खुद भी स्टैंडफोर्ड कोर्स कर रहा हूं और मैं यहां लंबे समय से अटका हुआ हूं, लेकिन कुछ खोज के बाद, मुझे यहां से कुछ मिला: Xcode के नोट्स जारी किए और इसमें कुछ नीचे दिए गए हैं:

स्विफ्ट 1.2 @objc विधियों और इनिशियलाइज़र के प्रकार-आधारित ओवरलोडिंग की जाँच करने के बारे में सख्त है, कुछ उद्देश्य-सी द्वारा समर्थित नहीं है।

// Has the Objective-C selector "performOperation:".
func performOperation(op: NSOperation) { /* do something */ }
// Also has the selector "performOperation:".
func performOperation(fn: () -> Void) {
    self.performOperation(NSBlockOperation(block: fn))
}

स्विफ्ट से मंगवाए जाने पर यह कोड काम करेगा, लेकिन ऑब्जेक्टिव-सी से मंगवाए जाने पर आसानी से क्रैश हो सकता है। इस समस्या को हल करने के लिए, एक प्रकार का उपयोग करें जो ऑब्जेक्ट-सी रनटाइम के लिए सदस्य को उजागर करने से स्विफ्ट कंपाइलर को रोकने के लिए ऑब्जेक्टिव-सी द्वारा समर्थित नहीं है:

  • यदि यह समझ में आता है, तो @objc की निष्क्रियता को अक्षम करने के लिए सदस्य को निजी के रूप में चिह्नित करें।
  • अन्यथा, डिफ़ॉल्ट मान के साथ डमी पैरामीटर का उपयोग करें, उदाहरण के लिए: _ nonobjc: () = ()। (19826275)

निजी उपवर्गों में ऑब्जेक्टिव-सी के सामने आने वाले तरीकों के ओवरराइड @objc होने का अनुमान नहीं लगाया जाता है, जिससे स्विफ्ट कंपाइलर क्रैश हो जाता है। स्पष्ट रूप से इस तरह के ओवरराइडिंग तरीकों में @objc विशेषता जोड़ें। (19935352)

किसी प्रोजेक्ट या कार्यक्षेत्र में तेज़ी से ओपन का उपयोग करते समय एसडीके से प्रतीक उपलब्ध नहीं होते हैं जो स्विफ्ट का उपयोग करते हैं। (20349540)

मैंने इस तरह ओवरराइड विधि के सामने सिर्फ "निजी" जोड़ा था:

    private func performOperation(operation: Double -> Double) {
    if operandStack.count >= 1 {
        displayValue = operation(operandStack.removeLast())
        enter()
    }
}




swift