"घातक त्रुटि: सरणी को उद्देश्य-सी से नहीं रोका जा सकता है" - आप स्विफ्ट की कोशिश भी क्यों कर रहे हैं?


92

मैंने एक स्विफ्ट प्रोटोकॉल घोषित किया है:

protocol Option {
    var name: String { get }
}

मैं इस प्रोटोकॉल के कई कार्यान्वयनों की घोषणा करता हूं - कुछ वर्ग, कुछ दुश्मनी।

मेरे पास इस तरह घोषित संपत्ति के साथ एक दृश्य नियंत्रक है:

var options: [Option] = []

जब मैं कोशिश करता हूं और इस संपत्ति को वस्तुओं के एक समूह में सेट करता हूं जो Optionप्रोटोकॉल को दूसरे वीसी में लागू करता है prepareForSegue, तो मुझे एक रनटाइम त्रुटि मिलती है:

fatal error: array cannot be bridged from Objective-C

यह काम क्यों नहीं करता है? कंपाइलर के पास वह सभी जानकारी है जिसकी उसे आवश्यकता है, और मुझे समझ नहीं आ रहा है कि ऑब्जेक्टिव-सी का उसके साथ क्या करना है- मेरी परियोजना में केवल स्विफ्ट फाइलें हैं, और ये सरणियाँ किसी भी फ्रेमवर्क विधियों में या उसके बाहर नहीं आ रही हैं आवश्यकता होती है उन्हें पाटने की NSArray


6
क्या आपने @objcअपने प्रोटोकॉल को प्रस्तुत करने की कोशिश की ? stackoverflow.com/a/28029568/377369
फैबियो पोलोनी

1
अगर कोई प्रोटोकॉल लागू नहीं होता है तो यह काम नहीं करता है: "नॉन-क्लास टाइप 'फू' क्लास प्रोटोकॉल 'ऑप्शन' के अनुरूप नहीं हो सकता है
रॉबर्ट एटकिंस

हालाँकि यह एक क्लास प्रोटोकॉल क्यों होना चाहिए? मैं इसे ओब्ज-सी फ्रेमवर्क या ऐसी किसी अन्य चीज़ से पारित नहीं कर रहा हूँ जिसके लिए स्विफ्ट ऐरे को NSArray के लिए तैयार होना चाहिए।
रॉबर्ट एटकिन्स

वे स्विफ्ट और ऑब्जेक्टिव-सी काम एक साथ करते हैं जो अभी भी मेरे लिए एक रहस्य है। मुझे बस कई चीजों को "स्वीकार" करना है जो सिर्फ "काम" या "काम नहीं करते" हैं।
फाबियो पोलोनी

9
यह एक बहुत सारे डाउनवोट क्यों है? मेरे लिए एक निष्पक्ष और स्पष्ट प्रश्न की तरह दिखता है।
ग्वेन

जवाबों:


83

मैंने एक उपाय खोज लिया है। यह काफी ... असंतोषजनक है , लेकिन यह काम करता है। जहाँ मैं गंतव्य व्यू कंट्रोलर पर सरणी सेट करता हूँ:

destinationViewController.options = options.map({$0 as Option})

क्या आप पूरी सरणी नहीं डाल सकते? options as [Option]
कोस्टिएंटिन कोवल

नहीं। कोशिश की (Xcode 6.3.1 (6D1002)), काम नहीं करता है। मुझे इसे किसी भी मामले में डालने की आवश्यकता नहीं है , संकलक जानता है कि मैं उन चीजों के एक सरणी में गुजर रहा हूं जो विकल्प को लागू करते हैं।
रॉबर्ट एटकिन्स

2
"चीजों की एक सरणी जो विकल्प को लागू करती है" आह, लेकिन वह विकल्प के एक सरणी के समान नहीं है, जो कि आपको चाहिए। मेरा जवाब देखिए।
मैट

1
यह काम करता है, और हाँ यह बहुत असंतोषजनक है ... इसकी आवश्यकता नहीं होनी चाहिए। स्विफ्ट को htis को संभालने में सक्षम होना चाहिए।
ऑस्कर गोमेज़

मैं सहमत हूं ... यह इस तरह से काम करता है, लेकिन यह कोड का बहुत असंतोषजनक है
माइकल

22

संकलक जानता है कि मैं उन चीजों के एक सरणी में गुजर रहा हूं जो विकल्प को लागू करते हैं

आपने बहुत ही चौकाने वाली टिप्पणी दी है, जो इस मुद्दे के स्रोत का सुझाव देती है। एक "चीजों का सरणी जो विकल्प को लागू करता है" विकल्प का एक सरणी नहीं है।

समस्या optionsउस बिंदु पर वापस के प्रकार के साथ है जहां आप इसे (इन prepareForSegue) बनाते हैं । आप उस कोड को नहीं दिखाते हैं, लेकिन मैं शर्त लगा रहा हूं कि आप इसे उस बिंदु पर डालने / टाइप करने में विफल होंगे। इसलिए असाइनमेंट फेल है। optionsविकल्प को अपनाने के लिए होने वाली चीजों की एक सरणी हो सकती है, लेकिन यह पर्याप्त नहीं है; यह विकल्प के एक सरणी के रूप में टाइप किया जाना चाहिए ।

तो, वापस prepareForSegueअपने optionsमें इस तरह से फार्म :

let options : [Option] = // ... whatever ...

अब आप इसे सीधे असाइन कर पाएंगे destinationViewController.options

यहां एक त्वरित परीक्षण मामला है (खेल के मैदान में; मैं खेल के मैदानों का पता लगाता हूं, लेकिन उनके उपयोग हो सकते हैं):

protocol Option {
    var name : String {get}
}

class ViewController : UIViewController {
    var options : [Option] = []
}

enum Thing : Option {
    var name : String {
        get {
            return "hi"
        }
    }
    case Thing
}

let vc = ViewController()
let options : [Option] = [Thing.Thing]
vc.options = options // no problem

(मैंने एक वास्तविक ऐप में prepareForSegueइसे वास्तविक रूप से भी जांचा , और यह ठीक काम करता है।)


1
मैं इस चरम में टूट गया है क्योंकि संकलक लगता है कार्यावधि में पता है कि बात एक विकल्प है। और किसी भी मामले में, जैसा कि नीचे दिए गए मेरे अपने जवाब के लिए टिप्पणी में उल्लेख किया गया है, न तो कास्टिंग ( viewController.options = things as [Option]) और न ही एक अस्थायी चर बनाने के लिए स्पष्ट रूप से टाइप किया [Option]गया जैसा कि आप यहां सुझाते हैं, वास्तव में काम करता है। दोनों ही मामलों में मुझे रनटाइम त्रुटि मिलती है।
रॉबर्ट एटकिन्स

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

शायद। लेकिन मैं अभी भी इस उलझन में हूं कि पहली जगह में ऑब्जेक्टिव-सी के साथ इसका क्या करना है (विज़ुअल, मूल रनटाइम एरर।) मैं कुछ भी नहीं कर रहा हूं (जो मैं देख सकता हूं) जिसे ब्रिजिंग कास्ट करने के लिए मजबूर करना चाहिए। NSArray।
रॉबर्ट एटकिन्स

2
इसे इस तरह देखो। मैंने आपको वह कोड दिखाया है जो काम करता है। आपने मुझे वह कोड नहीं दिखाया है जो काम नहीं करता है - मैं दिए गए डेटा से आपके मुद्दे को पुन: पेश नहीं कर सकता। मुझे इसे पुन: पेश करने में मदद करें।
मैट

1
@ CristiBăluță यह दावा करने से पहले आपको यह पता लगाना होगा कि "यह मुद्दा अभी भी तय नहीं हुआ है"
मैट

16

मुझे भी यही समस्या हो रही थी और यह तय किया कि मेरे प्रोटोकॉल को चिह्नित किया जाए @objc, आपके मामले में यह इस तरह दिखेगा

@objc protocol Option {
    var name: String { get }
}

इस उत्तर से समाधान मिल गया


1
मूल प्रश्न पर टिप्पणियों में के रूप में, यह काम नहीं करता है, अगर प्रोटोकॉल के कार्यान्वयन के किसी भी स्विफ्ट Enums हैं। मेरे मामले में वे कौन हैं।
रॉबर्ट एटकिन्स

टाइपो obcj objc होना चाहिए
एलन स्कार्पा

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